I am working on a Character Controller Script and everything is working fine but the problem is that once my player starts to fall it is so sudden and jerks down. I would like the player to gradually fall down, this is my character controller script -
using UnityEngine;
using System.Collections;
public class CharacterController : MonoBehaviour {
public float inputDelay = 0.1f;
public float forwardVel = 12;
public float rotateCel = 12;
public float JumpHeight = 20;
public Vector3 Gravity = new Vector3 (0, -180, 0);
public bool CanPress;
private float jumpTime;
public float _initialJumpTime = 0.4f;
//[HideInInspector]
public bool isGrounded;
Quaternion targetRotation;
Rigidbody rBody;
Vector3 forwardInput, turnInput;
public bool HasJumped;
public Quaternion TargetRotation
{
get {return targetRotation;}
}
// Use this for initialization
void Start () {
Physics.gravity = Gravity;
targetRotation = transform.rotation;
if (GetComponent<Rigidbody> ())
rBody = GetComponent<Rigidbody> ();
else {
Debug.LogError("Character Needs Rigidbody");
}
// forwardInput = turnInput = 0;
forwardInput = turnInput = Vector3.zero;
}
// Update is called once per frame
void Update () {
GetInput ();
//Turn ();
if (CanPress == true) {
if (Input.GetKeyDown (KeyCode.Space)) {
HasJumped = true;
jumpTime = _initialJumpTime;
}
}
if (HasJumped == true) {
rBody.useGravity = false;
jumpTime -= 1 * Time.deltaTime;
if (jumpTime > 0) {
Jump();
}
else {
HasJumped = false;
rBody.useGravity = true;
}
}
}
void GetInput() {
//forwardInput = Input.GetAxis ("Vertical");
//turnInput = Input.GetAxis ("Horizontal");
forwardInput = new Vector3 (Input.GetAxis ("Horizontal") * rotateCel, 0, Input.GetAxis ("Vertical") * forwardVel);
forwardInput = transform.TransformDirection (forwardInput);
if (Input.GetKeyUp (KeyCode.Space)) {
//HasJumped = false;
}
}
void Jump() {
Vector3 up = transform.TransformDirection (Vector3.up);
GetComponent<Rigidbody> ().AddForce (up * 5, ForceMode.Impulse);
}
void FixedUpdate() {
Run ();
}
void Run() {
if (Mathf.Abs (10) > inputDelay) {
//Move
//rBody.velocity = transform.forward * forwardInput * forwardVel;
rBody.velocity = forwardInput;
} else {
//zero velocity
rBody.velocity = Vector3.zero;
}
}
void Turn() {
// targetRotation *= Quaternion.AngleAxis (rotateCel * turnInput * Time.deltaTime, Vector3.up);
// transform.rotation = targetRotation;
}
void OnTriggerEnter(Collider col) {
isGrounded = true;
CanPress = true;
}
void OnTriggerExit(Collider col) {
isGrounded = false;
CanPress = false;
}
}
My character has a Rigidbody attactches which uses gravity and has X,Y,Z constraints for Rotation.
The player goes up smoothly and falls down smoothly but the transition between the two is very abrupt and sudden.
Thanks for the help. :)
Okay, so I took your code and had a play.
I think the issue was that in your Run() function, you were altering the velocity of the rigidbody which was affecting your jumping.
I've taken that stuff out and improved your script slightly and tested it. Attach this to a capsule with a rigidbody on it, with a floor underneath with a box collider on and hit space, and you should get a smooth jump.
Your new(ish) script:
using UnityEngine;
using System.Collections;
public class CharacterController : MonoBehaviour
{
public float inputDelay = 0.1f;
public float forwardVel = 12;
public float rotateCel = 12;
public float jumpHeight = 10;
private float jumpTime;
public float _initialJumpTime = 0.4f;
//[HideInInspector]
public bool isGrounded;
Quaternion targetRotation;
Rigidbody rBody;
Vector3 forwardInput, turnInput;
public bool canJump;
public Quaternion TargetRotation
{
get { return targetRotation; }
}
void Start()
{
targetRotation = transform.rotation;
if (GetComponent<Rigidbody>())
rBody = GetComponent<Rigidbody>();
else
{
Debug.LogError("Character Needs Rigidbody");
}
// forwardInput = turnInput = 0;
forwardInput = turnInput = Vector3.zero;
}
void Update()
{
GetInput();
//Turn ();
if (Input.GetKeyDown(KeyCode.Space) && canJump)
{
rBody.AddForce(Vector3.up * jumpHeight, ForceMode.Impulse);
}
}
void GetInput()
{
//forwardInput = Input.GetAxis ("Vertical");
//turnInput = Input.GetAxis ("Horizontal");
forwardInput = new Vector3(Input.GetAxis("Horizontal") * rotateCel, 0, Input.GetAxis("Vertical") * forwardVel);
forwardInput = transform.TransformDirection(forwardInput);
}
void FixedUpdate()
{
//Run();
}
void Run()
{
//HERE YOU SET THE RIGIDBODYS VELOCITY, WHICH IS CAUSING YOUR JUMP TO NOT WORK PROPERLY. DO NOT MODIFY THE VELOCITY
//OF A RIGIDBODY
if (Mathf.Abs(10) > inputDelay)
{
//Move
//rBody.velocity = transform.forward * forwardInput * forwardVel;
rBody.velocity = forwardInput;
}
else
{
//zero velocity
rBody.velocity = Vector3.zero;
}
}
void Turn()
{
// targetRotation *= Quaternion.AngleAxis (rotateCel * turnInput * Time.deltaTime, Vector3.up);
// transform.rotation = targetRotation;
}
void OnCollisionEnter(Collision col)
{
isGrounded = true;
canJump = true;
}
void OnCollisionExit(Collision col)
{
isGrounded = false;
canJump = false;
}
}
Couple of points:
name your variables inThisKindOfFashion (jumpHeight, isOnGround, camelCaseExample), having variables beginning with a capital letter like Gravity and JumpHeight can get confusing.
as someone once answered on one of my questions, don't modify the velocity of a rigidbody unless you know what you are doing! Seems odd, but after following that advice I've never had a problem since!
In your script I have used OnCollision rather than OnTrigger. If you put a floor with a box collider underneath your capsule with a collider, rigidbody and this script on, your character will stop on the ground. If you use a trigger, he will fall through (at least in my experience!)
Happy coding! :-)
Edit
To respond to your comments:
"How do you suggest I move the player"
Movement can be done in a variety of different ways, but I usually use this one all the time unless I need to do something a bit differently:
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
transform.position += Vector3.left * speed * Time.deltaTime; //speed could be 5f, for example (f means float);
}
// then do the same for other directions, RightArrow -.right, UpArrow - .forward, DownArrow - .back
}
"How do I adjust how fast the player jumps"
You can alter the jumpHeight variable for a higher or smaller jump. If by faster you mean falls down faster, go to Edit>Project Settings>Physics> and change Y gravity to something smaller, such as -20.
Tutorials can be found here
They have a wide variety of tutorials, and even have ones that come with example projects so you can just put it together following the video.
Related
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class teleporttospawn : MonoBehaviour
{
public GameObject player; /// player
public Transform fps; /// also player
private void OnTriggerEnter(Collider other)
{
Debug.Log("teleport succes.");
fps.transform.position = new Vector3(-3.82f, 1.08f, -1.69f); // DONT WORK
player.transform.position = new Vector3(-3.82f, 1.08f, -1.69f); //DONT WORK
}
}
I have two players in the script above because I tried to move it in two ways but nothing worked
So I tried to set the object to vector3 and try to move the player to the object, so nothing comes out
I need teleport player when he triger the collider. Debug.Log work but transform.position dont work.
Its dosent work from this script -> fpscontroller
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class fpscontroller : MonoBehaviour
{
public float walkingSpeed = 7.5f;
public float runningSpeed = 11.5f;
public float jumpSpeed = 8.0f;
public float gravity = 20.0f;
public Camera playerCamera;
public float lookSpeed = 2.0f;
public float lookXLimit = 45.0f;
CharacterController characterController;
Vector3 moveDirection = Vector3.zero;
float rotationX = 0;
[HideInInspector]
public bool canMove = true;
public GameObject tp;
private void OnTriggerEnter(Collider collision)
{
if (collision.gameObject.CompareTag("tp"))
{
while(transform.position != tp.transform.position)
{
Debug.Log("teleport succes.");
gameObject.transform.position = tp.transform.position;
}
}
}
void Start()
{
transform.position = gameObject.transform.position;
characterController = GetComponent<CharacterController>();
// Lock cursor
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
void Update()
{
// We are grounded, so recalculate move direction based on axes
Vector3 forward = transform.TransformDirection(Vector3.forward);
Vector3 right = transform.TransformDirection(Vector3.right);
// Press Left Shift to run
bool isRunning = Input.GetKey(KeyCode.LeftShift);
float curSpeedX = canMove ? (isRunning ? runningSpeed : walkingSpeed) * Input.GetAxis("Vertical") : 0;
float curSpeedY = canMove ? (isRunning ? runningSpeed : walkingSpeed) * Input.GetAxis("Horizontal") : 0;
float movementDirectionY = moveDirection.y;
moveDirection = (forward * curSpeedX) + (right * curSpeedY);
if (Input.GetButton("Jump") && canMove && characterController.isGrounded)
{
moveDirection.y = jumpSpeed;
}
else
{
moveDirection.y = movementDirectionY;
}
// Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
// when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
// as an acceleration (ms^-2)
if (!characterController.isGrounded)
{
moveDirection.y -= gravity * Time.deltaTime;
}
// Move the controller
characterController.Move(moveDirection * Time.deltaTime);
// Player and Camera rotation
if (canMove)
{
rotationX += -Input.GetAxis("Mouse Y") * lookSpeed;
rotationX = Mathf.Clamp(rotationX, -lookXLimit, lookXLimit);
playerCamera.transform.localRotation = Quaternion.Euler(rotationX, 0, 0);
transform.rotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * lookSpeed, 0);
}
}
}
I'm making a 2D platformer with Unity. I used this tutorial to write this code but changed it a little bit. I want to support both keyboard and gamepad, so I use the new Input System. I've defined three variables called GroundedRememeber, JumpPressedRemember and JumpPressedRememberTime and basically they work like timers and check if the player leaves the ground and then the player can jump when he is near the ground without need to touch it and I want to use it instead of famous "groundCheck". But the problem is that these timers are not working and the player can jump forever even in the air when I press jump button rapidly. Also, as you can see, I added a LayerMask named "groundLayers" for the player to jump only on this type of objects but when I choose "Ground" in the "groundLayers" slot in the Inspector, the player can't jump anymore.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour, PlayerInputActions.IPlayerActions
{
private PlayerInputActions controls;
[SerializeField] LayerMask groundLayers;
private Rigidbody2D rb;
private Animator anim;
private bool facingRight = true;
private Vector2 moveInput;
[SerializeField] private float jumpForce;
float JumpPressedRemember = 0;
[SerializeField] float JumpPressedRememberTime = 0.2f;
float GroundedRemember = 0;
[SerializeField] float GroundedRememberTime = 0.25f;
[SerializeField] float HorizontalAcceleration = 1;
[SerializeField] [Range(0, 1)] float HorizontalDampingBasic = 0.5f;
[SerializeField] [Range(0, 1)] float HorizontalDampingWhenStopping = 0.5f;
[SerializeField] [Range(0, 1)] float HorizontalDampingWhenTurning = 0.5f;
[SerializeField] [Range(0, 1)] float JumpHeight = 0.5f;
private void Awake()
{
controls = new PlayerInputActions();
controls.Player.SetCallbacks(this);
}
void Start()
{
rb = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
void PlayerInputActions.IPlayerActions.OnMove(InputAction.CallbackContext context)
{
moveInput = context.ReadValue<Vector2>();
}
void Jump() {
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Force);
GroundedRemember = 0;
JumpPressedRemember = 0;
}
bool TryJump() {
if (GroundedRemember > 0) {
Jump();
return true;
} else {
JumpPressedRemember = JumpPressedRememberTime;
return false;
}
}
void PlayerInputActions.IPlayerActions.OnJump(InputAction.CallbackContext context)
{
jumpForce = context.ReadValue<float>();
switch (context.phase) {
case InputActionPhase.Performed:
TryJump();
break;
}
}
void FixedUpdate()
{
if(facingRight == false && moveInput.x > 0){
Flip();
}else if (facingRight == true && moveInput.x < 0){
Flip();
}
}
void Flip(){
facingRight = !facingRight;
Vector3 Scaler = transform.localScale;
Scaler.x *= -1;
transform.localScale = Scaler;
}
void OnEnable()
{
controls.Enable();
}
void OnDisable()
{
controls.Disable();
}
void Update()
{
Vector2 GroundedBoxCheckPosition = (Vector2)transform.position + new Vector2(0, -0.01f);
Vector2 GroundedBoxCheckScale = (Vector2)transform.localScale + new Vector2(-0.02f, 0);
bool Grounded = Physics2D.OverlapBox(GroundedBoxCheckPosition, transform.localScale, 0, groundLayers);
GroundedRemember -= Time.deltaTime;
if (Grounded)
{
GroundedRemember = GroundedRememberTime;
}
JumpPressedRemember -= Time.deltaTime;
if ((JumpPressedRemember > 0)) {
TryJump();
}
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
float HorizontalVelocity = rb.velocity.x;
HorizontalVelocity += moveInput.x;
if (Mathf.Abs(moveInput.x) < 0.01f)
HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenStopping, Time.deltaTime * 10f);
else if (Mathf.Sign(moveInput.x) != Mathf.Sign(HorizontalVelocity))
HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenTurning, Time.deltaTime * 10f);
else
HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingBasic, Time.deltaTime * 10f);
rb.velocity = new Vector2(HorizontalVelocity, rb.velocity.y);
}
}
If you know how much the player jumps for, then try maybe adding a delay to the next jump
Maybe using the Invoke() function ur just using Coroutines if you know how to use them.
But i would still recommend using a Ground Check since it's practical and just easier and i don't see a reason why you wouldn't use it.
The grounded state for my character controller flickers on and off constantly at what seems to be every frame. From what I know, it's supposed to check if the player is grounded through player.isGrounded, but something else is moving it back up.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCharacterController: MonoBehaviour {
static Animator anim;
public bool walking;
public GameObject playerModel, Hero;
//Transforms
public Transform playerCam, character, centerPoint;
private Vector3 moveDirection;
//character controller declaration
CharacterController player;
//Mouse Rotation
private float rotX, rotY;
//Mouse Y Position
public float mouseYPosition = 1f;
//Mouse Sensitivity
public float Sensitivity = 10f;
//Mouse Zoom
private float zoom;
public float zoomSpeed = 2;
//Clamping Zoom
public float zoomMin = -2f;
public float zoomMax = -10f;
public float rotationSpeed = 5f;
//Move Front Back left & Right
private float moveFB, moveLR;
//Movement Speed
public float Speed = 2f;
//Velocity of Gravity
public float verticalVelocity;
//Jump Distance
public float jumpDist = 5f;
//Multiple Jumps
int jumpTimes;
//To use with Dialogue Manager
public DialogueManager DiagM;
public AudioClip jumpSound;
public AudioClip HurtSound;
public AudioClip PunchSound;
AudioSource audioSource;
//knockback
public float knockBackForce;
public float knockBackTime;
private float knockBackCounter;
// Use this for initialization
void Start ()
{
//character controller
player = GameObject.Find("Player").GetComponent<CharacterController> ();
StartCoroutine(MyCoroutine(character));
anim = GetComponent<Animator>();
//mouse zoom
zoom = -3;
centerPoint.transform.position = playerCam.transform.position;
centerPoint.transform.parent = null;
audioSource = GetComponent<AudioSource>();
}
IEnumerator MyCoroutine (Transform character)
{
if (player.isGrounded == true)
{
anim.SetBool("isFalling",false);
//anim.SetBool("isIdling", true);
yield return new WaitForSeconds(0);
}
}
// Update is called once per frame
void Update ()
{
//Mouse Zoom Input
zoom += Input.GetAxis ("Mouse ScrollWheel") * zoomSpeed;
if (zoom > zoomMin)
zoom = zoomMin;
if (zoom < zoomMax)
zoom = zoomMax;
//Mouse Camera Input
playerCam.transform.localPosition = new Vector3 (0, 0, zoom);
//Mouse Rotation
rotX += Input.GetAxis ("Mouse X") * Sensitivity;
rotY -= Input.GetAxis ("Mouse Y") * Sensitivity;
//Clamp Camera
rotY = Mathf.Clamp (rotY, -60f, 60f);
playerCam.LookAt (centerPoint);
centerPoint.localRotation = Quaternion.Euler (rotY, rotX, 0);
//Movement Speed
if (knockBackCounter <= 0)
{
moveDirection = (transform.forward * Input.GetAxis("Vertical")) + (transform.right * Input.GetAxis("Horizontal"));
moveDirection = moveDirection * Speed;
moveDirection.y = verticalVelocity;
player.Move(moveDirection * Time.deltaTime);
//Movement Rotation
centerPoint.position = new Vector3 (character.position.x, character.position.y + mouseYPosition, character.position.z);
//knockback disable
//Movement Input
if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)
{
transform.rotation = Quaternion.Euler(0f, centerPoint.rotation.eulerAngles.y, 0f);
Quaternion turnAngle = Quaternion.LookRotation(new Vector3(moveDirection.x, 0f, moveDirection.z));
playerModel.transform.rotation = Quaternion.Slerp(playerModel.transform.rotation, turnAngle, Time.deltaTime * rotationSpeed);
if (player.isGrounded == true)
{
anim.SetBool("isWalking", true);
anim.Play("Running");
}
}
else
{
StartCoroutine(MyCoroutine(character));
}
if (Input.GetButtonDown("LHand"))
{
audioSource.PlayOneShot(PunchSound, 1F);
anim.Play("RPunch");
}
if (player.isGrounded == true)
{
jumpTimes = 0;
//verticalVelocity = -Physics.gravity.y * Time.deltaTime;
verticalVelocity = 0;
}
else
{
verticalVelocity += Physics.gravity.y * Time.deltaTime;
anim.SetBool("isWalking", false);
anim.SetBool("isFalling", true);
}
if (jumpTimes < 1)
{
if (Input.GetButtonDown("Jump"))
{
verticalVelocity += jumpDist;
anim.Play("Jump");
audioSource.PlayOneShot(jumpSound, 1F);
jumpTimes += 1;
}
}
}
else
{
knockBackCounter -= Time.deltaTime;
}
}
public void Knockback(Vector3 direction)
{
knockBackCounter = knockBackTime;
anim.Play("Jump");
audioSource.PlayOneShot(HurtSound, 50F);
moveDirection = direction * knockBackForce;
moveDirection.y = knockBackForce;
}
}
It looks like it has to do with the verticalVelocity lines, but so far I have only tried setting verticalVelocity = 0 and that works until I have actually moved the character. What could I change to stop the flickering?
Probably it is already solved, but the reason for that is that if you are using Character Controller you should apply gravity ALL the time to the character.
When the character collides with a object, it actually enters a little bit inside this object, then Unity pushes the character back away from the object, until it is no longer touching it. At this point, your gravity starts acting again, and re initiziling the cycle.
You need to apply gravity 100% of the time to create enough force to "balance" this fight with the floor. Could be a smaller "gravity" like 1. No need to be your gravity variable.
Also, on top of that, I like to add a "Coyote time", and make my on IsGrounded() method, as follows:
public bool IsGrounded()
{
return CoyoteTime < CoyoteTimeMax;
}
public void CoyoteControl()
{
if (CharController.isGrounded)
{
CoyoteTime = 0;
}
else
{
CoyoteTime += Time.deltaTime;
}
}
And then I call the CoyoteControl() on Update(), and I can call IsGrounded() whenever I need.
On the inspector I usually set the CoyoteTimeMax to 0.1 and it makes falls more smooth.
As per you comment. You should not determine if your player is grounded by checking an animation parameter. The best way is to use a RayCast(). So what you have to do:
Create a Layer named Ground, and add all the platforms in your
scene to that layer.
Create a bool variable
i.e
bool isGrounded;
Create a function to check if the character is grounded
Something like:
bool checkGrounded(){
return Physics.Raycast(transform.position, Vector3.down, 2f, 1 << LayerMask.NameToLayer("Ground")));
}
In this answer you can read about the involved parameters in the Raycast
Finally inside the update check if the player is grounded or not
Something like:
void Update(){
isGrounded = checkGrounded();
}
I have found that the isGrounded check can change over the course of the Update() function if you are checking it multiple times. Assigning it to a variable at the beginning of the function may solve the flickering issue.
void Update()
{
bool isGrounded = characterController.isGrounded;
...
I'm trying to get the distance between my player, and the nearest object with the tag 'wall' however I can't seem to get it to work.
To my knowledge my code isn't working at all.
So my question is;
What am I doing wrong? Again, I want to find the distance from my player and the nearest object with the tag 'wall'. If I'm near a object with the tag 'wall' I want it to set the variable to true.(nearWall = true) then once I'm away from the object(About 10.0f) I want it back to false.(nearWall = false)
This is the code I have been working with.
using UnityEngine;
using System.Collections;
public class PlayerMotor : MonoBehaviour {
private CharacterController controller;
private Vector3 moveVector;
private float speed = 2.0f;
private float verticalVelocity = 0.0f;
private float gravity = 12.0f;
private bool nearWall;
public GameObject playerObject;
GameObject closestObject;
float distance = Mathf.Infinity;
public float distanceToWall = Mathf.Infinity;
private void Start() {
nearWall = false;
playerObject = GameObject.Find("Player");
distanceToWall = 0;
controller = GetComponent<CharacterController> ();
}
public void getNearestWall()
{
if (distance <= 10.0f) {
nearWall = true;
print ("Near wall!");
}
else
nearWall = false;
}
GameObject findNearestWall()
{
GameObject[]objectArray;
objectArray = GameObject.FindGameObjectsWithTag("wall");
Vector3 position = playerObject.transform.position;
foreach(GameObject currentObject in objectArray)
{
Vector3 distanceCheck = currentObject.transform.position - position;
float currentDistance = distanceCheck.sqrMagnitude;
if (currentDistance < distance)
{
closestObject = currentObject;
distance = currentDistance;
}
}
return closestObject;
}
private void Update()
{
findNearestWall ();
moveVector = Vector3.zero;
if (controller.isGrounded)
{
verticalVelocity = -0.5f;
}
else
{
verticalVelocity -= gravity * Time.deltaTime;
}
if (Input.GetMouseButton (0)) {
if (!nearWall) {
if (Input.mousePosition.x > Screen.width / 2)
moveVector.x = speed;
else
moveVector.x = -speed;
}
else
{
moveVector.x = transform.forward.x * speed;
transform.Rotate(new Vector3(0, -90, 0));
}
}
moveVector.y = verticalVelocity;
moveVector.z = transform.forward.z * speed;
controller.Move (moveVector * Time.deltaTime);
}
}
One thing is that you are not calling getNearestWall() method - which is actually changing the flag - anywhere.
And second why don't you just try:
currentDistance = Vector3.Distance(currentObject.transform.position, position);
When calculating distance
first of all you need to call getNearestWall(); inside the Update() method ( after findNearestWall() of course ). also what you are doing now is getting the minimal distance the player reached in the whole game. you might want to add distance = Mathf.Infinity; in top of findNearestWall() so it will something like this:
GameObject findNearestWall()
{
GameObject[] objectArray;
objectArray = GameObject.FindGameObjectsWithTag("wall");
distance = Mathf.Infinity;
Vector3 position = playerObject.transform.position;
foreach (GameObject currentObject in objectArray)
{
Vector3 distanceCheck = currentObject.transform.position - position;
float currentDistance = distanceCheck.sqrMagnitude;
if (currentDistance < distance)
{
closestObject = currentObject;
distance = currentDistance;
}
}
return closestObject;
}
now whenever you get near a wall it should print Near wall!
note:
also you are calling FindObjectsWithTag() at an Update method which might significantly drain your processing power. you might want to avoid that by declaring a private GameObject[] objectArray in the class.
and then use objectArray = GameObject.FindGameObjectsWithTag("wall"); once at Awake() or Start()
I'm working on a project where I'm trying to make my character move by jumping at an angle. Right now during the frame updates, the character will pivot back and forth and when the right key is pressed, they will jump. This code causes them to jump at an angle, but they always return to their original position.
Additionally, I have two characters who start on opposite sides of the stage, but when I start the game they teleport to the same position. I've spent a lot of time reviewing my code but I can't seem to get this to work. Any help you can provide?
using UnityEngine;
using System.Collections;
public class Freg : MonoBehaviour {
public GameObject Tounge;
public float gravity;
public float tempScale = 1;
public float MaxJump = 8f;
public float MinJump = 0.1f;
static float yVector = 0;
static float xVector = 0;
static bool grounded = true;
bool isleft = false;
Vector3 farthestleft;
Vector3 farthestright;
// Use this for initialization
void Start () {
farthestleft = new Vector3 (-33.7f, 50.2f, 24.8f);
farthestright = new Vector3 (22.56f, 54.83f, -15.12f);
}
void OnTriggerEnter (Collider other) {
if (other.GetComponent<Collider> ().tag == "Ground") {
grounded = true;
yVector = 0;
//xVector = 0;
Vector3 onGround = new Vector3 (transform.position.x, -4.86f, transform.position.z);
transform.position = onGround;
} else
grounded = false;
}
// Update is called once per frame
void Update () {
/*if (Input.GetKey (KeyCode.UpArrow) == true) {
Tounge.transform.localScale.Set (1, 0.5f, 1);
} else {
Tounge.transform.localScale.Set (1, 1, 1);
}*/
if (grounded == false) {
yVector -= gravity;
}
if (Input.GetKeyDown (KeyCode.UpArrow) == true && grounded == true) {
MinJump += 0.5f;
} else if (MinJump > 0.1f){
yVector += MinJump;
xVector += MinJump;
MinJump = 0.1f;
grounded = false;
}
Vector3 stuff = new Vector3 (transform.localPosition.y + xVector, transform.position.y + yVector, transform.position.z);
transform.position = stuff;
float t = Mathf.PingPong (Time.time * 0.5f * 2.0f, 1.0f);
transform.eulerAngles = Vector3.Lerp (farthestright, farthestleft, t);
}
}
it looks like you should update the current position during the if statements, rather than after that way on each update, the actual position is moving based on the decision rather than just the end of the loop.