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
Related
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've got a problem with my spherical world player controller. It randomly jitter all the time.
Planet uses Mesh Collider, and it's rigidbody is set too: "is kinematic" and continous collisions.
Player's rigidbody is set to: "interpolate" and continous collisions.
Here is player controller:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
[SerializeField] Transform cam, body, groundCheck;
[Space][SerializeField] float sensivity = 100f;
[SerializeField] float mass = 1f;
[SerializeField] float moveSpeed = 1f;
[SerializeField] float jumpHeight = 1f;
[SerializeField] LayerMask ground;
[SerializeField] float rotationChangeSpeed = 1f;
float xRotation = 0f;
Rigidbody rb;
Vector3 moveAmount, smoothMove;
Vector3 localUp;
bool grounded = false;
Quaternion targetRot;
float jumpTime = 0f;
Transform currentPlanet;
//On start
void Awake() {
Cursor.lockState = CursorLockMode.Locked;
rb = GetComponent<Rigidbody>();
}
//Physics simulation
void FixedUpdate() {
Grav();
FindingRotation();
Movement();
grounded = IsGrounded();
}
//Applying movement
void Movement() {
Vector3 localMove = transform.TransformDirection(moveAmount) * Time.fixedDeltaTime;
rb.MovePosition(rb.position + localMove);
}
//Simulating gravity
void Grav() {
List<CelestialBody> bodies = CelestialBody.bodies;
if(bodies.Count == 0) return;
Vector3 acceleration = Vector3.zero;
float maxForce = -1f;
for(int i = 0; i < bodies.Count; ++i) {
CelestialBody body = bodies[i];
float distance = Vector3.Distance(body.GetComponent<Transform>().position, transform.position);
float force = GravityManager.bigG * mass * body.mass / (distance * distance);
Vector3 direction = Vector3.Normalize(body.GetComponent<Transform>().position - transform.position);
if(force > maxForce) {
maxForce = force;
currentPlanet = body.transform;
}
acceleration += direction * force;
}
if(!grounded) GetComponent<Rigidbody>().AddForce(acceleration);
}
//Rotating according to body with highest gravity
void FindingRotation() {
localUp = Vector3.Normalize(transform.position - currentPlanet.position);
targetRot = Quaternion.FromToRotation(transform.up, localUp) * rb.rotation;
rb.rotation = Quaternion.Slerp(rb.rotation, targetRot, Time.fixedDeltaTime * rotationChangeSpeed);
}
//Per frame
void Update() {
CameraControls();
InputManager();
jumpTime -= Time.deltaTime;
}
//Camera controls
void CameraControls() {
float mouseX = Input.GetAxis("Mouse X") * sensivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * sensivity * Time.deltaTime;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
cam.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
body.Rotate(Vector3.up * mouseX);
}
//Moving and jumping
void InputManager() {
Vector3 inputRaw = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")).normalized;
Vector3 input = inputRaw * moveSpeed;
moveAmount = Vector3.SmoothDamp(moveAmount, input, ref smoothMove, .15f);
if(grounded) {
if(Input.GetKeyDown(KeyCode.Space)) {
rb.AddForce(transform.up * jumpHeight, ForceMode.VelocityChange);;
jumpTime = .2f;
grounded = false;
}
else {
if(jumpTime <= 0f) rb.AddForce (-transform.up, ForceMode.VelocityChange);
}
}
}
//TODO: Improve with ray
bool IsGrounded() {
return (Physics.OverlapSphere(groundCheck.position, .1f, ground).Length > 0);
}
}
And here is Celestial Body:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CelestialBody : MonoBehaviour
{
public static List<CelestialBody> bodies = new List<CelestialBody>();
public float mass;
//public Vector3 speed;
void OnEnable() {
bodies.Add(this);
}
void OnDisable() {
bodies.Remove(this);
}
}
I will be really grateful for any advice.
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.
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 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*/
}