I have a problem about jump for a character..
I can use CharacterMotor.Move() for jumping, but no .SimpleMove(), why?
This is my class at the moment:
public float speed = 10.0f;
public float rotationSpeed = 10.0f;
public float jumpSpeed = 50.0f;
public float gravitySpeed = 30.0f;
public string Avancer = "z";
public string Reculer = "s";
public string RotationGauche = "q";
public string RotationDroite = "d";
public string SlideGauche = "a";
public string SlideDroite = "e";
public string Jump = "space";
CharacterController cc;
Vector3 newPos;
public void Start()
{
cc = GetComponent<CharacterController> ();
}
public void Update()
{
/*Movements part*/
if (Input.GetKey (Avancer.ToString ())) {
newPos = new Vector3 (speed, 0, 0);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (Reculer.ToString ())) {
newPos = new Vector3 (speed * -1, 0, 0);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (SlideGauche.ToString ())) {
newPos = new Vector3 (0, 0, speed);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (SlideDroite.ToString ())) {
newPos = new Vector3 (0, 0, speed * -1);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (RotationGauche.ToString ())) {
transform.Rotate (0, rotationSpeed * -1, 0);
} else if (Input.GetKey (RotationDroite.ToString ())) {
transform.Rotate (0, rotationSpeed, 0);
} else if (cc.isGrounded && Input.GetKeyDown (Jump.ToString ())) {
newPos = new Vector3 (0, jumpSpeed * Time.deltaTime, 0);
cc.SimpleMove (newPos);
//cc.Move (newPos);
print ("JUMP !");
} else if (!cc.isGrounded) {
newPos = new Vector3 (0, (gravitySpeed * Time.deltaTime) * -1, 0);
cc.SimpleMove (newPos);
print ("en l'air");
}
/*Movements part*/
}
I just not understand why it don't perform
So if you can help me, thank you
EDIT
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[AddComponentMenu("Camera-Control/Mouse Look")]
public class palskie : MonoBehaviour
{
public float speed = 1000000.0f;
public float rotationSpeed = 10.0f;
public float jumpSpeed = 100.0f;
public float gravitySpeed = 50f;
public string Avancer = "z";
public string Reculer = "s";
public string RotationGauche = "q";
public string RotationDroite = "d";
public string SlideGauche = "a";
public string SlideDroite = "e";
public string Jump = "space";
private CharacterController cc;
Vector3 dir = Vector3.zero;
public int ammo = 100;
public int life = 100;
public void Start()
{
cc = GetComponent<CharacterController> ();
}
public void Update()
{
/*Movements part*/
Vector3 direction;// = Vector3.zero;
if (cc.isGrounded && Input.GetKeyDown (Jump.ToString ())) {
dir.y = jumpSpeed;
direction = dir;
} else if (!cc.isGrounded) {
dir.y -= gravitySpeed;
direction = dir;
} else {
direction = Vector3.zero;
}
if (Input.GetKey (Avancer.ToString ())) {
direction.x = speed;
} else if (Input.GetKey (Reculer.ToString ())) {
direction.x -= speed;
}
if (Input.GetKey (SlideGauche.ToString ())) {
direction.z = speed;
} else if (Input.GetKey (SlideDroite.ToString ())) {
direction.z = -speed;
}
if (Input.GetKey (RotationGauche.ToString ())) {
transform.Rotate (0, rotationSpeed * -1, 0);
} else if (Input.GetKey (RotationDroite.ToString ())) {
transform.Rotate (0, rotationSpeed, 0);
}
//Transformer le Vector3 en direction local
direction = transform.TransformDirection (direction);
//Deplacement du personnage
cc.Move (direction * Time.deltaTime);
transform.Rotate (0, Input.GetAxis ("Mouse X") * rotationSpeed, 0);
/*Movements part*/
}
void OnTriggerEnter(Collider obj)
{
if ((obj.gameObject.name == "Healt")) {
life += 5;
if (life > 100)
life = 100;
Destroy (obj.gameObject);
} else if ((obj.gameObject.name == "Ammo")) {
ammo += 5;
if (ammo > 200)
ammo = 200;
Destroy (obj.gameObject);
}
}
}
last edit, it works ! :) We found solution after long search ;)
Thank for you help :)
[SOLVED]
According to Unity, you can't and should not try to jump with the SimpleMove function. It clearly states on the documentation page of SimpleMove that SimpleMove will ignore any attempt to add force to the y-axis which is what you are doing. It is designed like that for thier own reason. Use the Move function as they made it for jumping.
Also the last line of your if statement code !cc.isGrounded is not required if you are using the SimpleMove function. The document again states that gravity is automatically applied to it when the object is moving.
For some reason I was able to get SimpleMove to work but the gravity pulling it down is too weak. If you want to try this, replace
newPos = new Vector3 (0, jumpSpeed * Time.deltaTime, 0);
with
newPos = new Vector3 (0, 1 * jumpSpeed * Time.deltaTime, 0);
then change the public float jumpSpeed = 50.0f;
to
public float jumpSpeed = 60000f;
It works but doesn't look good at all. You should go with the Move function instead.
EDIT:
"you say SimpleMove() can't do anything on Y-axis, then why my Y-axis is edit when I fall, I mean of gravaity?" It looks like you are doubting me. That's fine. It is your responsibility to click and read the the link I posted.
"The problem is, if I don't add gravity code, my character stay in fly, the other problem is, when I jump with Move(), It's like a teleportation" That's what you have said your problem was in the beginiing. It can be solve easily with the Move function by using Time.deltaTime to smooth out the y-axis movement.
Forget about the code I posted above. It worked but then stopped working after I restarted Unity. I guess it was a bug that made it to work in the first place.
I have changed your code to have smooth jumping with the Move function. I only changed the jumping and the gravity part of the code. Just copy the whole code and replace it with what you posted above. You shouldn't have any problem then. Make sure to reset the Character Controller values to default in Editor then reset the values of this script in the Editor too so that it will use the default values from the script. You can adjust the gravitySpeed and jumpSpeed to suit your needs after you test it.
public float speed = 10.0f;
public float rotationSpeed = 10.0f;
public float jumpSpeed = 130;
public float gravitySpeed = 80.0f;
public string Avancer = "z";
public string Reculer = "s";
public string RotationGauche = "q";
public string RotationDroite = "d";
public string SlideGauche = "a";
public string SlideDroite = "e";
public string Jump = "space";
CharacterController cc;
Vector3 newPos;
public void Start ()
{
cc = GetComponent<CharacterController> ();
}
public void Update ()
{
/*Movements part*/
if (Input.GetKey (Avancer.ToString ())) {
newPos = new Vector3 (speed, 0, 0);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (Reculer.ToString ())) {
newPos = new Vector3 (speed * -1, 0, 0);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (SlideGauche.ToString ())) {
newPos = new Vector3 (0, 0, speed);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (SlideDroite.ToString ())) {
newPos = new Vector3 (0, 0, speed * -1);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (RotationGauche.ToString ())) {
transform.Rotate (0, rotationSpeed * -1, 0);
} else if (Input.GetKey (RotationDroite.ToString ())) {
transform.Rotate (0, rotationSpeed, 0);
} else if (cc.isGrounded && Input.GetKeyDown (Jump.ToString ())) {
newPos = new Vector3 (0, jumpSpeed, 0);
cc.Move (newPos * Time.deltaTime);
print ("JUMP !");
}
if (!cc.isGrounded) {
newPos.y -= gravitySpeed * Time.deltaTime;
cc.Move (newPos * Time.deltaTime);
print ("en l'air");
}
/*Movements part*/
}
Related
I want to code the car's rotation system as I move left and right. I use the following code for this.
float steer = Input.GetAxis("Horizontal");
float finalangel = steer * 45f;
wheelcoll[0].steerAngle = finalangel;
But I want to set it for the phone. When the user touches the screen of the phone and keeps his hand on the screen of the phone, the car goes to the left and stays. When the user removes his hand from the phone, the car returns to its original position. But when doing this process, I want the car to turn in the right direction.
How can I do this?
I tried this too:
[SerializeField] Rigidbody rb;
public Vector3 targetpostion;
public int Speed;
public bool FirstLaneBlueCar;
public bool BlueCar;
public Vector2 Xpos;
public float rotatlerptime;
bool rottrue;
void Start()
{
rottrue = false;
BlueCar = false;
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
BlueCar = true;
rottrue = true;
LeftButtonPressed();
}else if (Input.GetMouseButtonUp(0))
{
BlueCar = true;
rottrue = true;
LeftButtonPressed();
}
if (!rottrue)
{
if (transform.position.x <= 4f)
{
Debug.Log(">-.5");
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, 0), rotatlerptime * Time.deltaTime);
}
if (transform.position.x >= 3f)
{
Debug.Log(">.5f");
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, 0), rotatlerptime * Time.deltaTime);
}
}
}
private void FixedUpdate()
{
transform.Translate(targetpostion, Space.World);
if (BlueCar)
{
if (FirstLaneBlueCar)
{
if (rottrue)
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, -60f, 0), rotatlerptime * Time.deltaTime);
Invoke("rot2", .1f);
}
Invoke("left", .1f);
}
else
{
if (rottrue)
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 60f, 0), rotatlerptime * Time.deltaTime);
Invoke("rot2", .1f);
}
Invoke("right", .1f);
}
}
}
public void rot2()
{
rottrue = false;
}
void left()
{
transform.position = Vector3.Lerp(transform.position, new Vector3(-Xpos.y, transform.position.y, transform.position.z), .08f);
}
void right()
{
transform.position = Vector3.Lerp(transform.position, new Vector3(-Xpos.x, transform.position.y, transform.position.z), .08f);
}
public void LeftButtonPressed()
{
if (FirstLaneBlueCar)
{
FirstLaneBlueCar = false;
}
else
{
FirstLaneBlueCar = true;
}
}
You can track the first touch position, and make the respective calculations in the Update method, comparing the previous touch position with the current one.
private void Update()
{
if (Input.touches.Length < 1)
return;
var touch = Input.touches[0];
var deltaPosition = touch.deltaPosition;
// Move the car according to the shift in touch position
}
You can also save the touch ID when the touch has just begun, so you can track the same touch later (user can have multiple fingers on the screen).
Use Touch.fingerId for that.
Let me just preface my question by saying I'm quite new to unity and programming as a whole. However I've been experimenting with some movement and after adding my falling function I've run into some trouble. Sometimes if I press play in Unity the character will start jittering quite heavy, every frame it also jumps between isInAir and isGrounded (as well as isInteracting). This causes my player to shake heavily and jitter forward as well.
Sometimes the falling animation will happen but my character falls really slowly, sometimes the animation doesn't work. Does anyone know how I can fix this?
Here is my PlayerLocomotion, the everything falling related is mentioned under HandleFalling.
using System.Collections.Generic;
using UnityEngine;
namespace FS
{
public class PlayerLocomotion : MonoBehaviour
{
PlayerManager playerManager;
Transform cameraObject;
InputHandler inputHandler;
public Vector3 moveDirection;
[HideInInspector]
public Transform myTransform;
[HideInInspector]
public AnimatorHandler animatorHandler;
public new Rigidbody rigidbody;
public GameObject normalCamera;
[Header("Ground & Air Detection Stats")]
[SerializeField]
float groundDetectionRayStartPoint = 0.5f;
[SerializeField]
float minimumDistanceNeededToBeginFall = 1f;
[SerializeField]
float groundDirectionRayDistance = 0.2f;
LayerMask ignoreForGroundCheck;
public float inAirTimer;
[Header("Movement Stats")]
[SerializeField]
float movementSpeed = 5;
[SerializeField]
float sprintSpeed = 7;
[SerializeField]
float rotationSpeed = 10;
[SerializeField]
float fallingSpeed = 45;
void Start()
{
playerManager = GetComponent<PlayerManager>();
rigidbody = GetComponent<Rigidbody>();
inputHandler = GetComponent<InputHandler>();
animatorHandler = GetComponentInChildren<AnimatorHandler>();
cameraObject = Camera.main.transform;
myTransform = transform;
animatorHandler.Initialize();
playerManager.isGrounded = true;
ignoreForGroundCheck = ~(1 << 10);
}
#region Movement
Vector3 normalVector;
Vector3 targetPosition;
private void HandleRotation(float delta)
{
Vector3 targetDir = Vector3.zero;
float moveOverride = inputHandler.moveAmount;
targetDir = cameraObject.forward * inputHandler.vertical;
targetDir += cameraObject.right * inputHandler.horizontal;
targetDir.Normalize();
targetDir.y = 0;
if (targetDir == Vector3.zero) targetDir = myTransform.forward;
float rs = rotationSpeed;
Quaternion tr = Quaternion.LookRotation(targetDir);
Quaternion targetRotation =
Quaternion.Slerp(myTransform.rotation, tr, rs * delta);
myTransform.rotation = targetRotation;
}
public void HandleMovement(float delta)
{
if (inputHandler.rollFlag) return;
if (playerManager.isInteracting) return;
moveDirection = cameraObject.forward * inputHandler.vertical;
moveDirection += cameraObject.right * inputHandler.horizontal;
moveDirection.Normalize();
moveDirection.y = 0;
float speed = movementSpeed;
if (inputHandler.sprintFlag)
{
speed = sprintSpeed;
playerManager.isSprinting = true;
moveDirection *= speed;
}
else
{
moveDirection *= speed;
}
Vector3 projectedVelocity =
Vector3.ProjectOnPlane(moveDirection, normalVector);
rigidbody.velocity = projectedVelocity;
animatorHandler
.UpdateAnimatorValues(inputHandler.moveAmount,
0,
playerManager.isSprinting);
if (animatorHandler.canRotate)
{
HandleRotation (delta);
}
}
public void HandleRollingAndSprinting(float delta)
{
if (animatorHandler.anim.GetBool("isInteracting")) return;
if (inputHandler.rollFlag)
{
moveDirection = cameraObject.forward * inputHandler.vertical;
moveDirection += cameraObject.right * inputHandler.horizontal;
if (inputHandler.moveAmount > 0)
{
animatorHandler.PlayTargetAnimation("Rolling", true);
moveDirection.y = 0;
Quaternion rollRotation =
Quaternion.LookRotation(moveDirection);
myTransform.rotation = rollRotation;
}
else
{
animatorHandler.PlayTargetAnimation("Backstep", true);
}
}
}
public void HandleFalling(float delta, Vector3 moveDirection)
{
playerManager.isGrounded = false;
RaycastHit hit;
Vector3 origin = myTransform.position;
origin.y += groundDetectionRayStartPoint;
if (Physics.Raycast(origin, myTransform.forward, out hit, 0.4f))
{
moveDirection = Vector3.zero;
}
if (playerManager.isInAir)
{
rigidbody.AddForce(-Vector3.up * fallingSpeed);
rigidbody.AddForce(moveDirection * fallingSpeed / 5f);
}
Vector3 dir = -moveDirection;
dir.Normalize();
origin = origin + dir * groundDirectionRayDistance;
targetPosition = myTransform.position;
Debug
.DrawRay(origin,
-Vector3.up * minimumDistanceNeededToBeginFall,
Color.red,
0.1f,
false);
if (Physics.Raycast(origin, -Vector3.up, out hit, minimumDistanceNeededToBeginFall, ignoreForGroundCheck))
{
normalVector = hit.normal;
Vector3 tp = hit.point;
playerManager.isGrounded = true;
targetPosition.y = tp.y;
if (playerManager.isInAir)
{
if (inAirTimer > 0.5f)
{
Debug.Log("You were in the air for " + inAirTimer);
animatorHandler.PlayTargetAnimation("Land", true);
inAirTimer = 0;
}
else
{
animatorHandler
.PlayTargetAnimation("Empty", false);
inAirTimer = 0;
}
playerManager.isInAir = false;
}
else
{
if (playerManager.isGrounded)
{
playerManager.isGrounded = false;
}
if (playerManager.isInAir == false)
{
if (playerManager.isInteracting == false)
{
animatorHandler
.PlayTargetAnimation("Falling", true);
}
Vector3 vel = rigidbody.velocity;
vel.Normalize();
rigidbody.velocity = vel * (movementSpeed / 2);
playerManager.isInAir = true;
}
}
if (playerManager.isInteracting || inputHandler.moveAmount > 0)
{
myTransform.position = Vector3.Lerp(myTransform.position, targetPosition, Time.deltaTime / 0.1f);
}
else
{
myTransform.position = targetPosition;
}
}
}
#endregion
}
}
I am trying to make a simple pong game where once the player or the enemy scores both of them get repositioned on the field.
I have this script on the enemy:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyBehavior : MonoBehaviour
{
Vector3 ballPosition;
Vector3 paddlePosition;
float movementSpeed = 0.1f;
public Transform target;
public float maxAngle = 35.0f;
private Quaternion baseRotation;
private Quaternion targetRotation;
// Start is called before the first frame update
void Start()
{
baseRotation = transform.rotation;
}
// Update is called once per frame
void Update()
{
ballPosition = GameObject.Find("Ball").transform.position;
paddlePosition = this.transform.position;
if (paddlePosition.z < ballPosition.z)
{
paddlePosition.z += movementSpeed;
}
else if (paddlePosition.z > ballPosition.z)
{
paddlePosition.z -= movementSpeed;
}
transform.position = paddlePosition;
Vector3 look = target.transform.position - transform.position;
look.z = 0;
Quaternion q = Quaternion.LookRotation(look);
if (Quaternion.Angle(q, baseRotation) <= maxAngle)
{
targetRotation = q;
}
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2.0f);
}
}
And then a goal script attached to the goal that looks like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Goal : MonoBehaviour
{
public GameObject Ball;
public GameObject Player;
public GameObject Enemy;
public Text Player2Score;
public Text Player1Score;
int Player2ScoreText = 0;
int Player1ScoreText = 0;
Rigidbody ballrig;
Rigidbody playerrig;
Rigidbody enemyrig;
public ParticleSystem Particles;
float timeLeft = 1.0f;
public bool slowMo = false;
// Start is called before the first frame update
void Start()
{
ballrig = Ball.GetComponent<Rigidbody>();
playerrig = Player.GetComponent<Rigidbody>();
enemyrig = Enemy.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
if (slowMo == true)
{
timeLeft -= Time.deltaTime;
if (timeLeft < 0)
{
slowMo = false;
timeLeft = 1.0f;
Time.timeScale = 1f;
}
}
}
private void OnTriggerEnter(Collider other)
{
if (other.name == "Ball" && name == "Player_Goal")
{
slowMo = true;
Time.timeScale = 0.5f;
Explode();
Player2ScoreText += 1;
Player2Score.text = ("" + Player2ScoreText);
Ball.transform.position = new Vector3(0f, 4f, 0f);
Player.transform.position = new Vector3(-20f, 2f, 0f);
Enemy.transform.position = new Vector3(20f, 2f, 0f);
ballrig.velocity = Vector3.zero;
ballrig.angularVelocity = Vector3.zero;
playerrig.velocity = Vector3.zero;
playerrig.angularVelocity = Vector3.zero;
enemyrig.velocity = Vector3.zero;
enemyrig.angularVelocity = Vector3.zero;
int whoGetsIt = Random.Range(0, 2);
if (whoGetsIt >= 1)
{
Vector3 Impulse = new Vector3(-10f, 5f, Random.Range(-10f, 10f));
Ball.GetComponent<Rigidbody>().AddForce(Impulse, ForceMode.Impulse);
}
else
{
Vector3 Impulse = new Vector3(10f, 0f, Random.Range(-10f, 10f));
Ball.GetComponent<Rigidbody>().AddForce(Impulse, ForceMode.Impulse);
}
}
else if (other.name == "Ball" && name == "Enemy_Goal")
{
slowMo = true;
Time.timeScale = 0.5f;
Explode();
Player1ScoreText += 1;
Player1Score.text = ("" + Player1ScoreText);
Ball.transform.position = new Vector3(0f, 4f, 0f);
Player.transform.position = new Vector3(-20f, 2f, 0f);
Enemy.transform.position = new Vector3(20f, 2f, 0f);
ballrig.velocity = Vector3.zero;
ballrig.angularVelocity = Vector3.zero;
playerrig.velocity = Vector3.zero;
playerrig.angularVelocity = Vector3.zero;
enemyrig.velocity = Vector3.zero;
enemyrig.angularVelocity = Vector3.zero;
int whoGetsIt = Random.Range(0, 2);
if (whoGetsIt >= 1)
{
Vector3 Impulse = new Vector3(-10f, 5f, Random.Range(-10f, 10f));
Ball.GetComponent<Rigidbody>().AddForce(Impulse, ForceMode.Impulse);
}
else
{
Vector3 Impulse = new Vector3(10f, 0f, Random.Range(-10f, 10f));
Ball.GetComponent<Rigidbody>().AddForce(Impulse, ForceMode.Impulse);
}
}
}
void Explode()
{
Particles.Play();
}
}
Now the ball gets repositioned correctly after someone scores but for some reason the player and the enemy do not.
Is it because they both have code in their update function so that code "overwrights" the repositioned command? And if so how can I get around that?
I can see that your players are using Rigidbody or Rigidbody2D.
Whenever a rigidbody is involved you should not set any position via transform but rather use the according rigidbody methods like MovePosition and MoveRotation or for directly setting them go through Rigibody.position and Rigidbody.rotation e.g.
....
slowMo = true;
Time.timeScale = 0.5f;
Explode();
Player2ScoreText += 1;
Player2Score.text = ("" + Player2ScoreText);
Ball.GetComponent<Rigidbody>().position = new Vector3(0f, 4f, 0f);
Player.GetComponent<Rigidbody>().position = new Vector3(-20f, 2f, 0f);
Enemy.GetComponent<Rigidbody>().position = new Vector3(20f, 2f, 0f);
ballrig.velocity = Vector3.zero;
ballrig.angularVelocity = Vector3.zero;
playerrig.velocity = Vector3.zero;
playerrig.angularVelocity = Vector3.zero;
enemyrig.velocity = Vector3.zero;
enemyrig.angularVelocity = Vector3.zero;
int whoGetsIt = Random.Range(0, 2);
....
And then also in the EnemyBehaviour -> It should be FixedUpdate and look like
public Rigidbody target;
Rigidbody ball;
Rigidbody ownRigidbody;
void Start()
{
baseRotation = transform.rotation;
// Get reference only ONCE and store them1
ball = GameObject.Find("Ball").GetComponent<Rigidbody>();
ownRigidbody = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate()
{
ballPosition = ball.position;
paddlePosition = ownRigidbody.position;
if (paddlePosition.z < ballPosition.z)
{
paddlePosition.z += movementSpeed;
}
else if (paddlePosition.z > ballPosition.z)
{
paddlePosition.z -= movementSpeed;
}
ownRigidbody.MovePosition(paddlePosition;)
Vector3 look = target.position - ownRigidbody.position;
look.z = 0;
Quaternion q = Quaternion.LookRotation(look);
if (Quaternion.Angle(q, baseRotation) <= maxAngle)
{
targetRotation = q;
}
ownRigidbody.MoveRotation(Quaternion.Slerp(ownRigidbody.rotation, targetRotation, Time.deltaTime * 2.0f));
}
since here you want smooth interpolated position
I started doing some simple stuff in Unity (goal is to make a great game) so I made a simple Player Controller.
public class PlayerController : MonoBehaviour
{
public float walkingSpeed;
public float jumpSpeed;
public bool jumpFlag = false;
public float maxJumpDistance = 1.0f;
Rigidbody rb;
Collider col;
Vector3 playerSize;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
col = GetComponent<Collider>();
playerSize = col.bounds.size;
}
// Update is called once per frame
void FixedUpdate()
{
WalkHandler();
JumpHandler();
}
void WalkHandler()
{
float horizonstalAxis = Input.GetAxis("Horizontal");
float verticalAxis = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(-horizonstalAxis * walkingSpeed * Time.deltaTime, 0, -verticalAxis * walkingSpeed * Time.deltaTime);
rb.MovePosition(transform.position += movement);
}
void JumpHandler()
{
float jumpAxis = Input.GetAxis("Jump");
//Debug.Log(jumpAxis);
if (jumpAxis > 0)
{
bool isGrounded = CheckGrounded();
if (jumpFlag != true && isGrounded)
{
jumpFlag = true;
Vector3 jumpVector = new Vector3(0, jumpSpeed * Time.deltaTime, 0);
rb.AddForce(jumpVector, ForceMode.VelocityChange);
}
}
else
{
jumpFlag = false;
}
}
bool CheckGrounded()
{
Vector3 checkerPoint = transform.position + new Vector3(0, -playerSize.y / 2, 0);
bool grounded = Physics.Raycast(checkerPoint, -Vector3.up, maxJumpDistance);
return grounded;
}
I came across a wierd problem. In some parts of the scene my method JumpHandler is not working. After reaching some z coordinates, the CheckGrounded returns False instead of True, even though the Raycast direction is set down.
Can anyone help?
I am working on my spaceship game. I have done a lot of things in it but now I am facing a problem. The controls of the game are made by Input.GetAxis.
What I want to do now is that once I take the thinger of the W key, for the player to continue move in the same direction or from others keys. I want the player to continue moving in the same direction as the last input and if the gamer will want to change its direction he will need to click on another button, and then it will start moving in another direction. I tried it by myself but I didn't succeed.
public float Force;
public Rigidbody rb;
public float speed;
public Done_Boundary boundary;
public float RotSpeed;
public GameObject shot;
public Transform shotSpawn;
public float fireRate;
private float nextFire;
/*public Text bullettext;
public int maxbullet = 35;
public int curbullet = 0;
public GameObject NoBulletP;
public bool bulletgiving = false;
public void OK()
{
NoBulletP.SetActive (false);
}*/
void Start()
{
//curbullet = maxbullet;
rb = GetComponent<Rigidbody> ();
}
void Update ()
{
//bullettext.text = "Bullets: " + curbullet;
if (Input.GetButton ("Fire1") && Time.time > nextFire)
{
/*if (curbullet == 0)
{
NoBulletP.SetActive (true);
if(!bulletgiving)
{
StartCoroutine (wait());
}
}
else if(curbullet > 0)
{
curbullet--;*/
Instantiate (shot, shotSpawn.position, shotSpawn.rotation);
nextFire = Time.time + fireRate;
GetComponent<AudioSource> ().Play ();
/*}
else if(curbullet < 0)
{
curbullet = 0;
}*/
}
}
void FixedUpdate ()
{
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
rb.velocity = transform.forward * moveVertical * speed;
transform.Rotate (0.0f,moveHorizontal * RotSpeed * Time.deltaTime,0.0f);
rb.position = new Vector3(Mathf.Clamp (rb.position.x, boundary.xMin, boundary.xMax), 0.0f, Mathf.Clamp (rb.position.z, boundary.zMin, boundary.zMax));
}
That's happening because Input.GetAxis("Horizontal") and Input.GetAxis("Vertical") gets a value of 0 when the key is not being pressed.
Change the the code in FixedUpdate() to this:
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = 0f;
if (Input.GetAxisRaw("Vertical") != 0f)
{
moveVertical = Input.GetAxisRaw("Vertical");
rb.velocity = transform.forward * moveVertical * speed;
}
transform.Rotate(0.0f, moveHorizontal * RotSpeed * Time.deltaTime, 0.0f);
rb.position = new Vector3(Mathf.Clamp(rb.position.x, boundary.xMin, boundary.xMax), 0.0f, Mathf.Clamp(rb.position.z, boundary.zMin, boundary.zMax));
rb.AddForce(transform.forward * Force);
}
I'm using GetAxisRaw because it gives a value of -1 or 1 when is pressed and 0 when its not.