Unity3D Character Continuously Moving Issue - c#

so I'm working on a project in Unity3D and I'm having the following issue:
When I initially start the game, the character is not moving, which is intended. Then, when I hit "W" to move, my character starts moving and animates. However, when I let off the key, she doesn't stop moving forward.
Even if I hit the "S" key to move backward, after I let up, she starts moving forward again while no keys are pressed, and for the life of me I can't figure out why.
Here's the script I'm using on her if that helps:
using UnityEngine;
using System.Collections;
public class PlayerScript : MonoBehaviour
{
private CharacterController controller;
public float speed = 20.0f;
private Vector3 moveDirection = Vector3.zero;
public float gravity = 20.0f;
private bool winState = false;
private bool loseState = false;
private bool isBlocking = false;
private Animator anim;
// Use this for initialization
void Start ()
{
controller = this.GetComponent<CharacterController>();
anim = GetComponent<Animator>();
anim.SetBool("Ready_Bool", true);
}
// Update is called once per frame
void FixedUpdate ()
{
//GameObject center = GameObject.Find("MiddleOfRing");
GameObject opponent = GameObject.Find("Opponent");
checkAnimations();
float turn = Input.GetAxis("Horizontal");
//print("Horizontal: " + turn);
if(turn < 0)
moveLeft();
else if(turn > 0)
moveRight();
float vertDirection = Input.GetAxis("Vertical");
//print ("Vertical: " + vertDirection);
print ("Controller Velocity: " + controller.velocity.magnitude); //for testing
if(controller.isGrounded)
{
moveDirection = transform.forward * vertDirection * speed;
anim.SetFloat("Speed", controller.velocity.magnitude);
}
if(vertDirection > 0)
moveForward(moveDirection);
else if(vertDirection < 0)
moveBackward(moveDirection);
else
controller.Move(moveDirection * Time.deltaTime);
moveDirection.y = moveDirection.y - gravity * Time.deltaTime;
transform.LookAt(opponent.transform.position);
opponent.transform.LookAt(this.transform.position);
}
void moveLeft()
{
GameObject opponent = GameObject.Find("Opponent");
transform.RotateAround(opponent.gameObject.transform.position, Vector3.up, speed/2 * Time.deltaTime);
//for testing purposes, to be replaced with actual AI
opponent.transform.RotateAround(transform.position, Vector3.up, speed/2 * Time.deltaTime);
//tells Animator character is moving left
anim.SetBool("MoveLeft_Bool", true);
anim.SetBool("MoveRight_Bool", false);
anim.SetBool("MoveForward_Bool", false);
anim.SetBool("MoveBackward_Bool", false);
}
void moveRight()
{
GameObject opponent = GameObject.Find("Opponent");
transform.RotateAround(opponent.gameObject.transform.position, Vector3.down, speed/2 * Time.deltaTime);
//for testing purposes, to be replaced with actual AI
opponent.transform.RotateAround(transform.position, Vector3.down, speed/2 * Time.deltaTime);
//tells Animator character is moving right
anim.SetBool("MoveRight_Bool", true);
anim.SetBool("MoveLeft_Bool", false);
anim.SetBool("MoveForward_Bool", false);
anim.SetBool("MoveBackward_Bool", false);
}
void moveForward(Vector3 move)
{
GameObject opponent = GameObject.Find("Opponent");
float distance = Vector3.Distance(this.transform.position, opponent.transform.position);
//keeps characters at a certain distance from each other
if(distance >= 3)
{
controller.Move(move * Time.deltaTime);
}
//tells Animator character is moving forward
anim.SetBool("MoveForward_Bool", true);
anim.SetBool("MoveRight_Bool", false);
anim.SetBool("MoveLeft_Bool", false);
anim.SetBool("MoveBackward_Bool", false);
}
void moveBackward(Vector3 move)
{
GameObject opponent = GameObject.Find("Opponent");
moveDirection = transform.forward * Input.GetAxis("Vertical") * speed;
controller.Move(move * Time.deltaTime);
//tells Animator character is moving backward
anim.SetBool("MoveBackward_Bool", true);
anim.SetBool("MoveRight_Bool", false);
anim.SetBool("MoveForward_Bool", false);
anim.SetBool("MoveLeft_Bool", false);
}
void checkAnimations()
{
AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0);
if(Input.GetKeyDown(KeyCode.E))
{
anim.SetTrigger("JabR_Trig");
checkHit();
isBlocking = false;
}
else if(Input.GetKeyDown(KeyCode.Q))
{
anim.SetTrigger("JabL_Trig");
checkHit();
isBlocking = false;
}
else if(Input.GetKey(KeyCode.B))
{
anim.SetTrigger("Block_Trig");
isBlocking = true;
}
else
{
isBlocking = false;
}
}
void checkHit()
{
GameObject opponent = GameObject.Find("Opponent");
float distance = Vector3.Distance(this.transform.position, opponent.transform.position);
if(distance <= 4.0f)
{
}
}
public bool getBlocking()
{
return isBlocking;
}
}
I think the problem may be that I'm using controller.velocity.magnitude incorrectly.
If anyone can help me out, I would appreciate it!

this line:
moveDirection = transform.forward * vertDirection * speed;
should be this:
moveDirection = transform.forward * vertDirection * speed * Time.deltaTime;
this else block:
else
controller.Move(moveDirection * Time.deltaTime);
should look like this:
else
controller.Move(Vector3.zero);

I actually figured it out. My animator didn't have one of the transitions set up, so the character was stuck in an animation.
Thanks!

Related

Unity3D go down on slopes with a animated character

I'm developping a 3D game Unity with a squirrel as the player.
I'm struggling with a problem of slopes. I know, there are a bunch of tutorial to go down a slope whithout 'floating in the air while walking' but I didn't find a fine solution. I think it's because of the horizontal animations of the squirrel (maybe). I have tried with addForce, with a modified speed, with gravity... (maybe I implemented it wrong). I know I can check if I'm in the air or not with CharacterController.isGrounded but I can't force the squirrel to stick on the slope while running or walking. I'm sorry by advance if my question is too vague or simple.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System;
public class Squirrel : MonoBehaviour {
Animator squirrel;
public float gravity = 1.0f;
private Vector3 moveDirection = Vector3.zero;
float axisH, axisV;
public static int munitions = 0;
Rigidbody rb;
[SerializeField]
float walkSpeed = 2f, runSpeed = 8f, rotSpeed = 100f, jumpForce = 350;
private bool isJumpKeyDown = false;
[SerializeField] bool isJumping = false;
Animator characterAnimator;
int JumpCount = 0;
public int MaxJumps = 1; //Maximum amount of jumps (i.e. 2 for double jumps)
[SerializeField] GameObject nb_munitions;
CharacterController characterController;
// Use this for initialization
void Start () {
munitions = 0;
squirrel = GetComponent<Animator>();
rb = GetComponentInChildren<Rigidbody>();
characterAnimator = GetComponent<Animator>();
JumpCount = MaxJumps;
characterController = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
GetInput();
nb_munitions.GetComponent<Text>().text = "Glands : " + munitions; //Affichage du score
Move();
}
private void FixedUpdate()
{
if (isJumpKeyDown)
{
squirrel.SetTrigger("jump");
JumpCount -= 1;
isJumpKeyDown = false;
}
}
public void GetInput()
{
axisV = Input.GetAxis("Vertical");
axisH = Input.GetAxis("Horizontal");
}
private void Move()
{
if (characterController.isGrounded)
{
//On the ground
}
else
{
//on the air
}
if (axisV > 0)
{
if (Input.GetKeyDown(KeyCode.LeftControl))
{
transform.position += Vector3.forward * walkSpeed * Time.deltaTime;
squirrel.SetBool("walk", true);
}
else
{
transform.position += Vector3.forward * runSpeed * Time.deltaTime;
squirrel.SetFloat("run", axisV);
squirrel.SetBool("walk", false);
}
}
else
{
squirrel.SetFloat("run", 0);
}
if (axisH != 0 && axisV == 0)
{
squirrel.SetFloat("h", axisH);
}
else
{
squirrel.SetFloat("h", 0);
}
if (axisH != 0)
{
transform.Rotate(Vector3.up * rotSpeed * Time.deltaTime * axisH);
}
if (Input.GetKeyDown(KeyCode.Space))
{
if (JumpCount > 0)
{
isJumpKeyDown = true;
}
}
//Call munitions
if (Input.GetKeyDown(KeyCode.LeftShift))
{
if (Squirrel.munitions > 0)
{
SpawnerScript.Instance.NewSpawnRequest();
munitions--;
}
}
}
}
You can try to get the angle of the slope and make it the pitch for the mesh of the squirrel.
I finally found the problem. My C# script "overwrited" the CharacterController and did not allow the squirrel to go down the slopes. Make sure you follow a move script that "respects" the CharacterController (if you pick one or you'll be fighting windmills).

How can I make the NPC move only vertical and horizontal and not diagonal with Vector2/3.MoveTowards and how can I make the NPC move only by tile

So I was trying to make a game just for fun and to learn for future use. So I encountered this problem in making the enemy NPC. I want it to follow me or chase me but I want the NPC to only move horizontal and vertical and I want the NPC to move per tile as well just like my Player.
Here's the video of how it looks
https://www.youtube.com/watch?v=CB_vdt1Z3nA
and here's the NPC script
public class ChaseScript : MonoBehaviour
{
public float speed;
private GameObject player;
private Transform player_transform;
void Start()
{
player = GameObject.Find("Player");
}
void Update()
{
player_transform = player.GetComponent<Transform>();
transform.position = Vector3.MoveTowards(transform.position, player_transform.position, speed * Time.deltaTime);
}
}
Here's my player controller
public void InputMove()
{
if (!isMoving)
{
input.x = Input.GetAxisRaw("Horizontal");
input.y = Input.GetAxisRaw("Vertical");
if (input.x != 0) input.y = 0;
if (input != Vector2.zero)
{
playerAnimation.SetParameterValue(animator);
var movePos = transform.position;
movePos.x += input.x;
movePos.y += input.y;
FacingForward.transform.position = movePos;
if (IsWalkable(movePos))
StartCoroutine(Move(movePos));
}
playerAnimation.SetParameterValueisMoving(animator);
}
if (Input.GetKey(KeyCode.LeftShift))
{
moveSpeed = 6f;
animator.speed = 1.5f;
}
else
{
moveSpeed = 4f;
animator.speed = 1f;
}
}
IEnumerator Move(Vector3 movePos)
{
isMoving = true;
while ((movePos - transform.position).sqrMagnitude > Mathf.Epsilon)
{
transform.position = Vector3.MoveTowards(transform.position, movePos, moveSpeed * Time.deltaTime);
yield return null;
}
transform.position = movePos;
isMoving = false;
}
private bool IsWalkable(Vector3 movePos)
{
if (Physics2D.OverlapCircle(movePos, 0.1f, SolidObjectLayer | NPC) != null)
{
return false;
}
return true;
}
What I did to my Player to move per tile is I just add 1 to transform so It'll be a constant movement but I don't know how to apply it on the NPC with the Vector3.MoveTowards but if it's not possible to do then it's fine
Check if this could work (you can adapt it to your 2D case)
using UnityEngine;
public class ChaseOrthoScript : MonoBehaviour
{
public float speed;
private GameObject player;
private Transform player_transform;
bool isMoving = false;
void Start()
{
player = GameObject.Find("Player");
player_transform = player.GetComponent<Transform>();
transform.LookAt(player_transform.position);
}
void Update()
{
if (transform.InverseTransformPoint(player_transform.position).z > 0) {
transform.position += transform.forward * speed * Time.deltaTime;
isMoving = true;
} else {
if (isMoving) {
float angle = Vector3.Angle(transform.forward, player_transform.position - transform.position);
transform.Rotate(Vector3.up, Mathf.Sign(angle) * 90);
isMoving = false;
} else if (transform.InverseTransformPoint(player_transform.position).z <= 0) { //player is back
transform.Rotate(Vector3.up, 180);
}
}
}
}
note that the player_transform = player.GetComponent<Transform>(); is moved to the Start(). Usually you dont want GetComponents in an update as you need to get it only once. ALso its much cleaner to have a public GameObject player; variable in the script and attach the reference in the editor that the player = GameObject.Find("Player");. Usually you dont want scene elements found by a hardcoded magic value in your code.
Hope that helps.

Unity AI character controller gravity

I am trying to add gravity to my "residents" of a town builder game. Basically the residents just walk around to a random location, wait 2 seconds then do it again. I am trying to add gravity to them so they don't float.
controller = GetComponent<CharacterController>();
moveDirection = Vector3.zero;
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
These four lines are the gravity lines I tried added and very weird things happen such as the resident teleporting up if it touches anything, even the ground. What can I do? I basically just want the residents not to float above the ground and follow the slopes of the land like regular walking.
Below is the whole code if its needed to help solve my problem.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Resident : MonoBehaviour
{
private Vector3 location;
private Quaternion rotation;
private int speed;
private Vector3 moveDirection = Vector3.zero;
private bool canRotate = true;
Vector3 moveVector;
CharacterController controller;
// Start is called before the first frame update
void Start()
{
transform.rotation *= Quaternion.Euler(-90, 0, 0);
controller = GetComponent<CharacterController>();
speed = 5;
SetRandomPos();
StartCoroutine(ExampleCoroutine());
}
void Update()
{
int gravity = 20;
moveDirection = Vector3.zero;
//Check if cjharacter is grounded
moveDirection.y -= gravity * Time.deltaTime;
// Move the controller
controller.Move(moveDirection * Time.deltaTime);
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, location, step);
if (canRotate)
{
transform.LookAt(location);
transform.rotation *= Quaternion.Euler(-90, 90, 0);
canRotate = false;
}
if (transform.position == location)
{
StartCoroutine(ExampleCoroutine());
}
}
void SetRandomPos()
{
location = new Vector3(Random.Range(transform.position.x - 10f, transform.position.x + 10f), transform.position.y, Random.Range(transform.position.z - 10f, transform.position.z + 10f));
canRotate = true;
}
IEnumerator ExampleCoroutine()
{
//yield on a new YieldInstruction that waits for 5 seconds.
yield return new WaitForSeconds(2);
//After we have waited 5 seconds print the time again.
if (transform.position == location)
{
SetRandomPos();
}
}
}
I am not exactly clear what you intend to do, but saw a few issues with the code and tried to fix them. The snippet is untested, I just added what I believe to be the correction that should fix your issues.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
private Vector3 location;
private Coroutine changeMovement = null;
private float speed;
private Vector3 playerVelocity = Vector3.zero;
CharacterController controller;
// Start is called before the first frame update
void Start()
{
controller = GetComponent<CharacterController>();
speed = 5;
SetRandomPos();
}
void Update()
{
bool groundedPlayer = controller.isGrounded;
if (groundedPlayer && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
Vector3 move = (transform.position - location).normalized;
controller.Move(move * Time.deltaTime * speed);
if (move != Vector3.zero)
{
gameObject.transform.forward = move;
}
// check if we are close to our goal, then change the goal
if (changeMovement == null && Vector3.Distance(transform.position,location) < 0.1f)
{
changeMovement = StartCoroutine(ExampleCoroutine());
}
playerVelocity.y += gravityValue * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
}
void SetRandomPos()
{
location = new Vector3(Random.Range(transform.position.x - 10f, transform.position.x + 10f), transform.position.y, Random.Range(transform.position.z - 10f, transform.position.z + 10f));
}
IEnumerator ExampleCoroutine()
{
//yield on a new YieldInstruction that waits for 5 seconds.
yield return new WaitForSeconds(2);
SetRandomPos();
changeMovement = null;
}
Edit: I changed the code and used the CharacterController.Move as a base.

Character doesn't jump sometimes - Unity

I am new to Unity and I am using the following CharacterController for my character. Everything is working well, except that sometimes the character jumps and sometimes it doesn't when I hit the spacebar. I used Debog.Log using Raycast to check if my character is grounded, and the result was True. So what is preventing my character from jumping whenever I hit the key?
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(CharacterController))]
public class RPGMovement : MonoBehaviour
{
public float ForwardSpeed = 8f;
public float BackwardSpeed = 4f;
public float StrafeSpeed = 5f;
public float RotateSpeed = 110f;
CharacterController m_CharacterController;
Vector3 m_LastPosition;
Animator m_Animator;
PhotonView m_PhotonView;
PhotonTransformView m_TransformView;
float m_AnimatorSpeed;
Vector3 m_CurrentMovement;
float m_CurrentTurnSpeed;
Vector3 playerVelocity;
private bool groundedPlayer;
private float jumpHeight = 0.9f;
private float gravityValue = -20.81f;
void Start()
{
m_CharacterController = GetComponent<CharacterController>();
m_Animator = GetComponent<Animator>();
m_PhotonView = GetComponent<PhotonView>();
m_TransformView = GetComponent<PhotonTransformView>();
}
void Update()
{
if (m_PhotonView.isMine == true)
{
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
MoveCharacterController();
UpdateJump();
ApplySynchronizedValues();
}
UpdateAnimation();
}
void UpdateAnimation()
{
Vector3 movementVector = transform.position - m_LastPosition;
float speed = Vector3.Dot(movementVector.normalized, transform.forward);
float direction = Vector3.Dot(movementVector.normalized, transform.right);
if (Mathf.Abs(speed) < 0.2f)
{
speed = 0f;
}
if (speed > 0.6f)
{
speed = 1f;
direction = 0f;
}
if (speed >= 0f)
{
if (Mathf.Abs(direction) > 0.7f)
{
speed = 1f;
}
}
m_AnimatorSpeed = Mathf.MoveTowards(m_AnimatorSpeed, speed, Time.deltaTime * 5f);
m_Animator.SetFloat("Speed", m_AnimatorSpeed);
m_Animator.SetFloat("Direction", direction);
m_LastPosition = transform.position;
}
void ResetSpeedValues()
{
m_CurrentMovement = Vector3.zero;
m_CurrentTurnSpeed = 0;
}
void ApplySynchronizedValues()
{
m_TransformView.SetSynchronizedValues(m_CurrentMovement, m_CurrentTurnSpeed);
}
void MoveCharacterController()
{
m_CharacterController.Move(m_CurrentMovement * Time.deltaTime);
}
void UpdateForwardMovement()
{
if (Input.GetKey(KeyCode.W) || Input.GetAxisRaw("Vertical") > 0.1f)
{
m_CurrentMovement = transform.forward * ForwardSpeed;
}
}
void UpdateBackwardMovement()
{
if (Input.GetKey(KeyCode.S) || Input.GetAxisRaw("Vertical") < -0.1f)
{
m_CurrentMovement = -transform.forward * BackwardSpeed;
}
}
void UpdateStrafeMovement()
{
if (Input.GetKey(KeyCode.Q) == true)
{
m_CurrentMovement = -transform.right * StrafeSpeed;
}
if (Input.GetKey(KeyCode.E) == true)
{
m_CurrentMovement = transform.right * StrafeSpeed;
}
}
void UpdateRotateMovement()
{
if (Input.GetKey(KeyCode.A) || Input.GetAxisRaw("Horizontal") < -0.1f)
{
m_CurrentTurnSpeed = -RotateSpeed;
transform.Rotate(0.0f, -RotateSpeed * Time.deltaTime, 0.0f);
}
if (Input.GetKey(KeyCode.D) || Input.GetAxisRaw("Horizontal") > 0.1f)
{
m_CurrentTurnSpeed = RotateSpeed;
transform.Rotate(0.0f, RotateSpeed * Time.deltaTime, 0.0f);
}
}
void UpdateJump()
{
groundedPlayer = m_CharacterController.isGrounded;
if (groundedPlayer && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
if (Input.GetButtonDown("Jump") && groundedPlayer)
{
playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
m_Animator.SetTrigger("Jump");
print("Jumping Now");
}
playerVelocity.y += gravityValue * Time.deltaTime;
m_CharacterController.Move(playerVelocity * Time.deltaTime);
}
}
Best guess is that "m_PhotonView.isMine" is not returning true on the frames where you're missing input. It only checks jump input for that frame, so if the last frame you pressed it but jumping wasn't checked then that input is lost forever. First test this. Change the update code to this:
void Update()
{
if (Input.GetButtonDown("Jump")) { Debug.Log("Jump was pressed at {Time.time}"); }
if (m_PhotonView.isMine == true)
{
if (Input.GetButtonDown("Jump")) { Debug.Log("Attempting Jump at {Time.time}"); }
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
MoveCharacterController();
UpdateJump();
ApplySynchronizedValues();
}
UpdateAnimation();
}
Then play the game and jump a bunch. The first debug log line should happen every time you click the spacebar no matter what. The second debug line would only happen if physics are calculated that frame. Both have times attached. Keep jumping until the jump doesn't work. If that jump only produces the first debug log and not the second, then I am correct and that is your issue.
If so, then it's an easy fix. Add a new bool variable called "jumpInput". Whenever you check if jump was pressed, instead check if "jumpInput" is true. Then, change update to this:
void Update()
{
if (Input.GetButtonDown("Jump")) { jumpInput = true; }
if (m_PhotonView.isMine == true)
{
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
MoveCharacterController();
UpdateJump();
ApplySynchronizedValues();
jumpInput = false;
}
UpdateAnimation();
}
This way if you pressed jump, it's set to true... but it's only set to false after physics are done. So if you press jump on frame 20 and physics are somehow not calculated until frame 25, it'll still know that you pressed jump at some point and thus execute it. If you're using networking, you might want to also have another variable that's what frame jump was pressed. That way you can figure out how many frames it's been since input and compensate for missed time in the jump if necessary.

Player's Bumpy Movement

When my player jumps and lands on something it always shakes around like that.
Also, sometimes when I jump a few times in a row (about 10 times) it would go through the ground and just fall down.
I tried using a collider and I don't see anything in the movement script that may cause this. I'm currently using Unity 2018.4.20f1 and Visual Studio c#.
Any solutions?
Player Movement script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public static int movespeed = 6;
public Vector3 userDirection = Vector3.right;
public Rigidbody rb;
public bool isGrounded;
Vector3 jumpMovement;
bool jump = false;
[SerializeField]
float jumpHeight = 1.8f, jumpSpeed = 8f;
void Start()
{
rb = GetComponent<Rigidbody>(); }
void OnCollisionStay()
{
isGrounded = true;
}
public float fallMultiplier = 3.5f;
public float lowJumpMultiplier = 2f;
void Update()
{
//movement
transform.Translate(userDirection * movespeed * Time.deltaTime);
if (Input.GetButton("Jump") && !jump)
StartCoroutine(Jump());
}
IEnumerator Jump()
{
float originalHeight = transform.position.y;
float maxHeight = originalHeight + jumpHeight;
jump = true;
yield return null;
while (transform.position.y < maxHeight)
{
transform.position += transform.up * Time.deltaTime * jumpSpeed;
yield return null;
}
while (transform.position.y > originalHeight)
{
transform.position -= transform.up * Time.deltaTime * jumpSpeed;
yield return null;
}
rb.useGravity = true;
jump = false;
yield return null;
}
}
Edit: I didn't notice the link.
You are forcing it to go down to originalHeight, without checking if there is an object higher than that. You can remove
while (transform.position.y > originalHeight)
{
transform.position -= transform.up * Time.deltaTime * jumpSpeed;
yield return null;
}
and let the rigidbody control gravity (by setting rb.useGravity = true; as you did).
Original answer:
You are probably going below the ground when calling transform.position -= transform.up * Time.deltaTime * jumpSpeed;. Try adding
if (transform.position.y < originalHeight)
transform.position = new Vector3(transform.position.x, originalHeight, transform.position.z)
after it.

Categories