Player touch input and continuous one direction movement combination - unity3d

I want to create Mmm Finger 2 game like player movement, here is game play video: Mmm Fingers 2 by Noodlecake Android Gameplay ᴴᴰ
In this player is continuously moving upward as well based on touch, you have full control over player movement. These both things together not working properly for me. Finger based movement also working in all directions still you are continuously moving up.
I have tried to write some code with different ways but can't able to create smooth experience in game play.
Upto now I reached up to here:
void Update ()
{
// checking condition for death
if (!isAlive)
return;
#if UNITY_EDITOR
// executed in Unity editor
if (Input.GetMouseButtonDown (0)) {
//Get the mouse position on the screen and send a raycast into the game world from that position.
Vector2 worldPoint = Camera.main.ScreenToWorldPoint (Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast (worldPoint, Vector2.zero);
//If something was hit, the RaycastHit2D.collider will not be null.
if (hit.collider != null && hit.transform.CompareTag (GameConstants.TAG_HUMAN_PLAYER)) {
playerFound = true;
GameManager.Instance.IsGameRunning = true;
GameHUDController.Instance.HideGameInstruction();
hidePlayerName();
}
} else if (Input.GetMouseButtonUp (0)) {
playerFound = false;
StartCoroutine (PerformGameOver ());
}
Vector3 nextPosition = transform.position;
nextPosition.x += (Time.deltaTime * speed * 0.5f);
transform.position = nextPosition;
if (playerFound) {
Vector3 worldPoint = Camera.main.ScreenToWorldPoint (Input.mousePosition);
// worldPoint.x += (speed * Time.deltaTime);
worldPoint.z = 0f;
transform.position = worldPoint;
// transform.position = Vector3.Lerp (transform.position, worldPoint, Time.deltaTime * 10f);
}
}
Please give some help into this.

Related

How can I make a 2D gun shoot towards the Direction of the mouse rather than the Position of the mouse?

Currently, my gun is able to instantiate new bullets that work fine (they have velocity and shoot towards the mouse's position). However, if the mouse is close to the player, I noticed the velocity is drastically lessened because it is targeting the mouse's position instead of the general direction.
Is there a way to get the angle from the player to the mouse, as well as apply velocity to the bullet, without it going exactly to the mouse's position?
public GameObject bullet;
public GameObject player;
// All the following is within an update function
//Gets the mouse position, and assigns direction from gun to mouse
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 direction = mousePosition - transform.position;
float angle = Vector2.SignedAngle(Vector2.right, direction);
Vector2 PlayerDimensions = player.transform.lossyScale;
Vector2 PlayerLocation = player.transform.position;
//If the Gun weapon type is selected
if (weaponType == 2)
{
// Is used to flip the player sprite based on if the gun is facing left or right
if (PlayerLocation.x > mousePosition.x)
{
PlayerDimensions.x = -1;
player.transform.localScale = new Vector2(PlayerDimensions.x, PlayerDimensions.y);
}
else if (PlayerLocation.x < mousePosition.x)
{
PlayerDimensions.x = 1;
player.transform.localScale = new Vector2(PlayerDimensions.x, PlayerDimensions.y);
}
// Aims the gun based on if player is facing left or right
if (player.transform.lossyScale.x > 0)
{
transform.eulerAngles = new Vector3(0, 0, angle);
}
else if (player.transform.lossyScale.x < 0)
{
transform.eulerAngles = new Vector3(0, 0, 180 + angle);
}
}
if (Input.GetMouseButtonDown(0) && weaponType == 2)
{
Debug.Log("Shoot");
Vector3 myPos = new Vector3(transform.position.x, transform.position.y);
GameObject Bullet = Instantiate(bullet, myPos, Quaternion.identity);
Physics2D.IgnoreCollision(Bullet.GetComponent<BoxCollider2D>(), player.GetComponent<BoxCollider2D>(), GameObject.Find("blue_bullet_medium(Clone)"));
Bullet.GetComponent<Rigidbody2D>().velocity = new Vector2(direction.x, direction.y);
}
You can use normalized vector and speed instead of just direction to get constant bullet speed. In code it will be like this:
Vector2 direction = mousePosition - transform.position;
direction.Normalize();
Vector2 bulletVelocity = direction * _speed; // assume _speed can be tuned
The normalized vector will always have length 1, so the speed will not depend on the distance from the player to the cursor position

Unity3D Part Movement

With the help from people here (and the Unity forum) I am almost happy with the build i am making.
This build is showing a Booster Pump, used for boosting waterpressure for industrial cleaning.
So far i can zoom, rotate, Pan and press keys 1-3 to show/hide internal parts.
I would like to make the internal parts MOVE out to position on keypress, instead of just appearing in position (like they do now - 1st. image), so I have this movement script.
But when i rotate/move the Booster Pump, the it does not look right (2nd image).
The moved part is not following the main part of the Booster Pump.
From what I gather it have to do with local or world space, but I dont know which and how to implement it?
enter image description here
enter image description here
{
Vector3 EndPos;
Vector3 StartPos;
private float distPos;
public float MovSpeed;
private float direction = 0f; // The direction of travel
public float maxDistance = 2f; // The maximum move distance
void Start()
{
StartPos = transform.position;
EndPos = StartPos + Vector3.back * maxDistance;
}
void Update()
{
if (Input.GetKey(KeyCode.Space) && distPos == 1f)
direction = -1f;
if (Input.GetKey(KeyCode.Space) && distPos == 0f)
direction = 1f;
distPos = Mathf.Clamp01(distPos + (Time.deltaTime * MovSpeed * direction));
if (distPos == 0f || distPos == 1f) direction = 0f;
transform.position = Vector3.Lerp(StartPos, EndPos, distPos);
}
If the internal parts are child objects of the parent, and you want them to move around independently while also continuing to rotate and move with their parent, you should change their localPositions. By changing local position instead of world, you are telling them to move that distance away from their initial positions, relative to the center of their parent - no matter where the parent is or how it's rotated at the time.
Try changing
StartPos = transform.position;
to
StartPos = transform.localPosition;
and then change
transform.position = Vector3.Lerp(StartPos, EndPos, distPos);
to
transform.localPosition = Vector3.Lerp(StartPos, EndPos, distPos);

Raycast only returns false, even when true expected

I have the following FollowingNPC game object, which is supposed to follow the Player object if there is direct vision:
Here the Player object:
The BlockingLayer and Player Layers have the physics collision enabled between each other:
The FollowingNPC hast the following script attached, that always returns a "Not Hit" result: Raycast always false. This is not the expected output, as both objects seem to have a clear view between each other and the debug ray can be drawn without problems.
public class FollowingNPC : MonoBehaviour
{
private Vector3 heading, direction;
private float distance;
void Update()
{
heading = GameObject.FindGameObjectWithTag("Player").transform.position - transform.position;
distance = heading.magnitude;
direction = heading / distance;
RaycastHit hit;
if (Physics.Raycast(transform.position, direction, out hit))
{
if (hit.transform== GameObject.FindGameObjectWithTag("Player").transform)
{
Debug.DrawRay(transform.position, direction * distance, Color.red);
Debug.Log("Hit Player");
}
else
{
Debug.DrawRay(transform.position, direction * distance, Color.yellow);
Debug.Log("Hit Wall");
}
}
else
{
Debug.DrawRay(transform.position, direction * distance, Color.white);
Debug.Log("Not Hit");
}
}
}
Solved:
As derHugo suggested, Physics2D.Raycast should be used here. This function does not return a bool, so this is the implementation that worked for me:
void Update()
{
heading = GameObject.FindGameObjectWithTag("Player").transform.position - transform.position;
RaycastHit2D hit = Physics2D.Raycast(transform.position, heading.normalized, LayerMask.GetMask("Player"));
if (hit.collider != null)
if (hit.transform == GameObject.FindGameObjectWithTag("Player").transform)
Debug.Log("Hit Player");
else
Debug.Log("Hit Wall");
else
Debug.Log("Not Hit");
}
Also, it's important to note that, even with the mask, the Raycast returned the hit with the collider of FolloginNPC, so I had to disable it. I'll have to do some investigation or search a workaround.
Note that in Unity the Physics and Physics2D are completely independent and separated Physics engines!
Built-in 3D physics (Nvidia PhysX engine integration)
Built-in 2D physics (Box2D engine integration)
You have Rigidbody2D and Collider2D so you would rather want to use Physics2D.Raycast!
You should also strongly avoid using FindGameObjectWithTag in Update and even worse multiple times as it is quite expensive! Rather do it once and store the result.
// If possible and best would be to already reference it via the Inspector
[SerilaizeField] private Transform player;
// As fallback get it ONCE on runtime
private void Awake()
{
if(!player) player = GameObject.FindGameObjectWithTag("Player").transform;
}
void Update()
{
// actually those wouldn't really need to be fields
heading = player.position - transform.position;
distance = heading.magnitude;
// This line isn't really necessary
// If something I would use
//direction = heading.normalized
direction = heading / distance;
var hit = Physics2D.Raycast(transform.position, direction);
if (hit.collider)
{
if (hit.transform == player)
{
Debug.DrawRay(transform.position, direction * distance, Color.red);
Debug.Log("Hit Player");
}
else
{
Debug.DrawRay(transform.position, direction * distance, Color.yellow);
Debug.Log("Hit Wall");
}
}
else
{
Debug.DrawRay(transform.position, direction * distance, Color.white);
Debug.Log("Not Hit");
}
}
Later you should also remove all these Debug.Log since they are also quite expensive when done in Update!

Unity 2D - Tap Image to accelerate car

I am making a Hill Climb Racing clone as a school project. Currently my car is accelerating with the A and D keys in my editor (movement = Input.GetAxis("Horizontal");), however the game has to be for Android, therefore like in the OG game, I added 2 sprites for brakes and pedals and added EventSystems to them eg.:
public void OnPointerDown(PointerEventData eventData)
{
gas.sprite = OnSprite_gas;
is_clicking = true;
}
and I dont know how to change acceleration to when the gas image is clicked and held down and how to brake (but not go backwards) when the brake is held down.
You seem to be on the right track.
In the car's Update() method, you will want to check if the brake or accelerator button is_clicking property is set, and handle the movement force.
This could look something like:
void Update()
{
if (accelerator.is_clicking)
{
movement = new Vector3(1f, 0f, 0f) * speed;
}
else if (brake.is_clicking)
{
movement = new Vector3(-1f, 0f, 0f) * speed;
}
else
{
movement = new Vector3(0f, 0f, 0f);
}
}
void FixedUpdate()
{
rb.AddForce(movement * Time.fixedDeltaTime);
}
You could then check if the velocity is close to 0 to stop applying the brake force.

Unity 2D Shooter - Arm Rotation

I'm making a 2D platformer game where the player has an arm that points towards the mouse cursor. This mechanism is used to aim the player's weapon. However, I am experiencing some glitches when rotating the arm.
I know the reason why I am getting these errors: The arm (in the hierarchy) is a child of the player, and what I'm doing to the player is flipping (inverting) its transform.localScale.x value whenever it moves in a specified direction, so that the player sprite looks in the given direction. Since the arm is a child of the player, its own transform is flipped as well, making it look in the same direction as the player, which is what I want. However, this causes some errors with the arm rotation. Since the arm's transform.localScale.x value is flipped, the rotation is all messed up, and I can't figure out how to solve it.
Here are some example scripts for moving the player and arm. They are simplified so that you can read it better.
// Update is called once per frame
void Update () {
var input = Input.GetAxis("Horizontal");
if(input > 0) {
if(!facingRight) {
ChangeOrientation(gameObject, new Vector3(-1,1,1));
facingRight = !facingRight;
}
}
if(input < 0) {
if(facingRight) {
ChangeOrientation(gameObject, new Vector3(-1,1,1));
facingRight = !facingRight;
}
}
rbody.velocity = new Vector2(speed * input, rbody.velocity.y);
}
public static void ChangeOrientation (GameObject g, Vector3 changeBy) {
var newTransform = g.transform.localScale;
newTransform.x *= changeBy.x;
newTransform.y *= changeBy.y;
newTransform.z *= changeBy.x;
g.transform.localScale = newTransform;
}
And my arm rotation script:
void Update () {
//rotation
Vector3 mousePos = Input.mousePosition;
mousePos.z = 0;
Vector3 objectPos = Camera.main.WorldToScreenPoint (transform.position);
mousePos.x = mousePos.x - objectPos.x;
mousePos.y = mousePos.y - objectPos.y;
float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(new Vector3(0, 0,
(PlayerRunMovementController.facingRight ? angle : angle )));
}
Thanks for any help you can offer.