i'm working on Android touch button can shooting with no luck until now, my need to have button with name fire inside the canvase , can do the following:
1 - when pressed: shoot one bullet
2 - keep pressing: shoots bullets
3 - stop press: hold shooting
i need help to update the following code with above needs:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerShoot : MonoBehaviour {
public GameObject Ammo; // the shot
GameObject FiredShot;
public AudioClip bcgMusic;
public List<GameObject> ShotsOnAir;
//public AudioClip sound1; // Use this for initialization
void Start (){
ShotsOnAir = new List<GameObject>();
}
//update is called once per frame
void Update (){
if (Input.GetKeyDown(KeyCode.Mouse0)){
//if (Input.GetButtonDown("Fire1")){
FiredShot = (GameObject)Instantiate(Ammo,transform.position,transform.rotation);
ShotsOnAir.Add(FiredShot);
AudioSource.PlayClipAtPoint (bcgMusic, transform.position);
}
if(ShotsOnAir != null){
int i=0;
foreach (GameObject GB in ShotsOnAir){
ShotsOnAir[i].transform.position += ShotsOnAir[i].transform.forward * 200 * Time.deltaTime;
i++;
}
}
}
}
its solved after use Input.Touch insted of Input.GetKeyDown after follow the comment by programmer
Related
I implemented input for my mobile game like so:
I have some buttons and I have anywhere else on the screen.
Basically when the player touches the screen and not a button ingame, the character jumps. Now, It is implemented by using OnPointerDown and OnPointerUp that sets a bool:
public class JumpInput : MonoBehaviour
{
public static bool JUMP;
public void PointerDown()
{
JUMP = true;
}
public void PointerUp()
{
JUMP = false;
}
}
If the player is jumping, it is checked by a FixedUpdate method:
if (!movementDisabled && grounded && JumpInput.JUMP)
{
//then we can jump
currentImageIndex = 0;
animState = CharAnimStates.jumpStart;
//added again from here
//zeroing out the Y axis velocity if we had one
rb2d.velocity = new Vector2(rb2d.velocity.x, 0.0f);
//until here
jump = true;
}
As I get decent frame rates even when using post-processing, I have no clue why the input is so delayed. I require assistance to verify if my solution for "anywhere on the screen input" is viable performancewise and it not, how to improve it.
Hey guys so Im making my first app. I know this is a pretty loaded question but Im having a hard time following examples because the script code is different. I am making a 2D platform runner. To start, I created the platforms, environment as well as a majority if not all of the physics. The player at this point is just a circle (just a place holder). The circle can move from left to right and jump. I have now, created an actual player sprite and made animations for walking, jumping and idle. How do I apply the new sprite animations to the current circle placeholder as well as the script? My next step is to go into the animator and start making transitions i guess. Im just not sure how to add the animations to my current script. I knew this was going to be a challenge and if there is any other info you need, please let me know. Thanks so much guys.
This is my "Controls.cs" that is currently attached to my circle player/placeholder. My CheckGround is attached to him. Everything else should be in relation to the platforms he is jumping on and I dont think will change. Again, I have a sprite walking, jumping and idle that I would like to take place of the current circle/placeholder. I need the walking animation to take place when the left and right arrows are pressed, the pump animation to play when the jump button is pressed and idle animation to play when the player is just standing still otherwise. Again, thanks so much guys!
using UnityEngine;
using System.Collections;
public class Controls : MonoBehaviour
{
public Rigidbody2D rb;
public float movespeed;
public float jumpheight;
public bool moveright;
public bool moveleft;
public bool jump;
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask whatIsGround;
private bool onGround;
// Use this for initialization
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
onGround = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.LeftArrow))
{
rb.velocity = new Vector2(-movespeed, rb.velocity.y);
}
if (Input.GetKey(KeyCode.RightArrow))
{
rb.velocity = new Vector2(movespeed, rb.velocity.y);
}
if (Input.GetKey(KeyCode.Space))
{
if (onGround)
{
rb.velocity = new Vector2(rb.velocity.x, jumpheight);
}
}
if (jump)
{
if (onGround)
{
rb.velocity = new Vector2(rb.velocity.x, jumpheight);
}
jump = false;
}
if (moveright)
{
rb.velocity = new Vector2(movespeed, rb.velocity.y);
}
if (moveleft)
{
rb.velocity = new Vector2(-movespeed, rb.velocity.y);
}
}
}
Read about Animation Controller. After you create it you can grab Animator from your gameObject like transform.GetComponent<Animator>()
Later you can blend your animations or just play them. Unity give you even possibility to make input conditions to play your animations so to be honest you don't even have to type too much code.
Definitely use an Animation Controller.
Have a look at this video - I'm following this tutorial at the moment.
https://www.youtube.com/watch?v=I0IVZhHNarg
I am making a game in which my player is a UFO, and when the player collides with other game objects, I need the game objects to be attached or floated in the air below the player (UFO), like original UFO. I tried to attach them as a child, but it didn't worked.
I made one script as below:
if (coll) {
distance = Vector2.Distance (this.transform.position, player.transform.position);
if (distance < 2) {
this.transform.parent = encaixe.transform;
this.transform.localPosition = new Vector2 (0f, 1.2f);
this.transform.localRotation = Quaternion.identity;
encaixe.rigidbody2D.gravityScale=0;
}
}
In using this script, the gameobject is attaching, but the player is not moving as like original. The game object is pulling down or up forcefully.
Please suggest to me how to do this.
I know that this Thread is rather old, but maybe someone might come across this question and is in need of an answer.
You can actively set the Object's Position and Rotation to the UFO's on Collision.
Something like the following (pseudocode):
private bool hasCollided = false;
void OnCollisionEnter()
{
hasCollided = true;
}
void LateUpdate()
{
if (hasCollided)
{
followPlayer();
}
}
void followPlayer()
{
//update position and rotation
}
Please see the below images.
In the first image you can see that there is box collider.
The second image is when I run the code on Android device
Here is the code which is attached to Play Game (its a 3D Text)
using UnityEngine;
using System.Collections;
public class PlayButton : MonoBehaviour {
public string levelToLoad;
public AudioClip soundhover ;
public AudioClip beep;
public bool QuitButton;
public Transform mButton;
BoxCollider boxCollider;
void Start () {
boxCollider = mButton.collider as BoxCollider;
}
void Update () {
foreach (Touch touch in Input.touches) {
if (touch.phase == TouchPhase.Began) {
if (boxCollider.bounds.Contains (touch.position)) {
Application.LoadLevel (levelToLoad);
}
}
}
}
}
I want to see if touch point is inside the collider or not. I want to do this because right now if I click any where on the scene
Application.LoadLevel(levelToLoad); is called.
I want it to be called if I click on PLAY GAME text only. Can any one help me with this piece of code or can give me another solution to my problem??
Recent Code by following Heisenbug's Logic
void Update () {
foreach( Touch touch in Input.touches ) {
if( touch.phase == TouchPhase.Began ) {
Ray ray = camera.ScreenPointToRay(new Vector3(touch.position.x, touch.position.y, 0));
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity, 10)) {
Application.LoadLevel(levelToLoad);
}
}
}
}
Touch's position is expressed in screen space coordinate system (a Vector2). You need to convert that position in the world space coordinate system before trying to compare it against other 3D locations of objects in the scene.
Unity3D provides facility to do that. Since you are using a BoundingBox surrounding your text, you can do the following:
Create a Ray which origin is in the touch point position and which direction is parallel to the camera forward axis (Camera.ScreenPointToRay).
Check if that ray intersect the BoundingBox of your GameObject (Physic.RayCast).
the code may look something like that:
Ray ray = camera.ScreenPointToRay(new Vector3(touch.position.x, touch.position.y, 0));
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerOfYourGameObject))
{
//enter here if the object has been hit. The first hit object belongin to the layer "layerOfYourGameObject" is returned.
}
It's convenient to add a specific layer to your "Play Game" GameObject, in order to make the ray colliding only with it.
EDIT
Code and explanation above is fine. If you don't get a proper collision maybe you have not used the right layer. I haven't a touch device at the moment. The following code will work with mouse (without using layers).
using UnityEngine;
using System.Collections;
public class TestRay : MonoBehaviour {
void Update () {
if (Input.GetMouseButton(0))
{
Vector3 pos = Input.mousePosition;
Debug.Log("Mouse pressed " + pos);
Ray ray = Camera.mainCamera.ScreenPointToRay(pos);
if(Physics.Raycast(ray))
{
Debug.Log("Something hit");
}
}
}
}
It's just an example to put you in the right direction. Try to figure out what's going wrong in your case or post an SSCCE.
I was trying to make the enemies in my game go up and down; since I'm using a physic body with a Sprite on it I can't use entity modifiers, so I decided give the body a little push using the .setLinearVelocity(float x, float y) method every time its sprite reach a certain point in the screen.
With just one body works great, but I need to have other enemeis (same sprite, different body) spawning every 5 seconds and doing the same thing, but I don't know how to track them... I mean, I don't know how to control if each body reaches the Y location independently from one another...
For example, right now the code is like this:
private void add_Box_Face()
{
float random_x = (float) (28 + (int)(Math.random() * ((this.CAMERA_WIDTH - 28*2) + 1)));
final Body rectangle_face_body;
final Sprite rectangle_face = new Sprite(random_x, this.y, this.mRectangleFaceTextureRegion, this.getVertexBufferObjectManager());
rectangle_face_body = PhysicsFactory.createBoxBody(this.m_PhysicsWorld, rectangle_face, BodyType.DynamicBody, this.BOX_FIXTURE_DEF);
rectangle_face_body.setUserData("target");
//I give the body a initial push
rectangle_face_body.setLinearVelocity(0, -5);
//I register an update handler to the sprite to control if it reaches a certain Y value
rectangle_face.registerUpdateHandler(new IUpdateHandler()
{
#Override
public void onUpdate(float pSecondsElapsed)
{
if (rectangle_face.getY() >= y-50)
{
//Here I just use a flag so that later on below I can do the push
MyApp.this.setLinearVelocity = true;
}
}
#Override
public void reset()
{
// TODO Auto-generated method stub
}
});
//Here I register the physic connector and if the flag permits it, I push the body up
this.m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(rectangle_face, rectangle_face_body, true, false)
{
#Override
public void onUpdate(float pSecondsElapsed)
{
super.onUpdate(pSecondsElapsed);
if(MyApp.this.setLinearVelocity)
{
rectangle_face_body.setLinearVelocity(0, -3);
MyApp.this.setLinearVelocity = false;
}
}
});
this.mscene.attachChild(rectangle_face);
}
With the code like this the first body do what is planned, it moves up and down but as soon as another body pops up, it falls down and the other body goes up because the boolean setLinearVelocity is always set to true, so there is a costant push upwards; when a third body comes in, the second body falls down as well and this last one takes its place going up
With this code I didn't expect much else... but I don't know what else I can try... how can I control this?
Thanks in advance :)
EDIT: Added working code in an anwser below
I suggest you separate the code for the enemy from the code for the update handler. Create a class Enemy that will contain the Sprite and Body, hold your Enemies in an array and override the onUpdate method of your PhysicsWorld so that it goes through the array of Enemies and does what you want to all of them.
Here's a code snippet showing a very simple way of doing this:
mEngine.registerUpdateHandler(new IUpdateHandler() {
#Override
public void reset() {}
#Override
public void onUpdate(float pSecondsElapsed) {
for (Enemy e : enemies) {
e.checkPositionAndBounce();
}
}
});
Please note that this may not a very good idea as this code will probably run on a thread different to the one of the physics engine, which could cause all sorts of problems. A better way would be overriding the onUpdate method of PhysicsWorld:
#Override
public void onUpdate(final float pSecondsElapsed) {
super.onUpdate();
for (Enemy e : enemies) {
e.checkPositionAndBounce();
}
}
If you are unsure of what the first snippet means, look up "anonymous inner class".
Ok, here's the final working code (I didn't create a method to check the position or a class for the enemies just because right now I'm just messing around with the mechanics; I'll create a new project when I'm ready to really start):
this.m_PhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false)
{
#Override
public void onUpdate(float pSecondsElapsed)
{
super.onUpdate(pSecondsElapsed);
for(int i = 0; i <= MyApp.this.mSpriteCounter; i++)
{
if (rectangle_face[i].getY() >= y-50)
{
final PhysicsConnector spritePhysicsConnector = m_PhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(rectangle_face[i]);
spritePhysicsConnector.getBody().setLinearVelocity(0, -3);
}
}
};
In this code rectangle_face[] is an array of Sprites; each sprite is created like this:
private void add_Box_Face()
{
float random_x = (float) (28 + (int)(Math.random() * ((this.CAMERA_WIDTH - 28*2) + 1)));
final Body rectangle_face_body;
rectangle_face[this.mSpriteCounter] = new Sprite(random_x, y, this.mRectangleFaceTextureRegion, this.getVertexBufferObjectManager());
rectangle_face_body = PhysicsFactory.createBoxBody(this.m_PhysicsWorld, rectangle_face[this.mSpriteCounter], BodyType.DynamicBody, this.BOX_FIXTURE_DEF);
rectangle_face_body.setUserData("target");
rectangle_face_body.setLinearVelocity(0, -5);
this.m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(rectangle_face[this.mSpriteCounter], rectangle_face_body, true, false));
this.mscene.attachChild(rectangle_face[this.mSpriteCounter]);
}
That's it, thanks again for the help :)