I want to move an object along a ray gradually,
I have the following code so far which moves it in 1 frame to the destination rather than smoothly gliding there.
If I remove the Destroy(projectile.rigidbody2D) line from the end it sort of does it but then bounces around all over the place?
Any help would be much appreciated!
void Update ()
{
if (Input.GetMouseButtonUp (1)) {
if (Hand.transform.childCount == 1){
projectile.gameObject.transform.parent = null;
Ray ray = new Ray(spawn.position,spawn.up);
RaycastHit hit;
float shotDistance = shotdistance;
if (Physics.Raycast(ray,out hit, shotDistance)) {
shotDistance = hit.distance;
}
projectile.AddComponent<Rigidbody2D>();
projectile.rigidbody2D.gravityScale = 0;
projectile.rigidbody2D.AddForce(Vector2.up * 5);
projectile.transform.position = Vector3.MoveTowards(projectile.transform.position,ray.direction * shotDistance,shotDistance);
Debug.DrawRay(ray.origin,ray.direction * shotDistance,Color.red,1);
Destroy(projectile.rigidbody2D);
}
}
}
private float lerpValue = 0;
public float speed;
private Vector3 startPosition;
private bool isMoving;
void Update ()
{
if (Input.GetMouseButtonUp (1))
{
if (Hand.transform.childCount == 1)
{
lerpValue = 0;
startPosition = projectile.transform.position;
projectile.gameObject.transform.parent = null;
Ray ray = new Ray(spawn.position,spawn.up);
RaycastHit hit;
float shotDistance = shotdistance;
if (Physics.Raycast(ray,out hit, shotDistance) && !isMoving)
{
isMoving = true;
shotDistance = hit.distance;
//speed = distance / time
//therefore: time = distance / speed
float time = shotDistance / speed;
StartCoroutine(ProjectileMotion(hit.point, time));
}
}
}
}
IEnumerator ProjectileMotion(Vector3 endPosition, float time)
{
while(lerpValue < time)
{
lerpValue += Time.deltaTime;
projectile.transform.position = Vector3.Lerp(startPosition, endPosition, lerpValue / time);
}
isMoving = false;
}
Related
So I want to make a 2.5d grappling rope that lets the player swing around objects for quicker turning, but the code that I wrote doesn't work. The player just stops all velocity after a short amount of time.
public Transform player;
private float tikTok;
public LayerMask layerMask;
Vector3 tetherPoint;
Transform tetherObject;
Vector3 currentTether;
float tetherLength;
bool isTethered;
Vector3 previousPlayerPosition;
if (Input.GetKey(KeyCode.Space) && Time.time >= tikTok && !isTethered) {
// this part works fine and dandy
Ray ray = new Ray(player.position, player.forward);
if (Physics.Raycast(ray, out RaycastHit hit, float.MaxValue, layerMask)) {
tetherPoint = hit.point;
tetherObject = hit.transform;
currentTether = tetherObject.position;
tetherLength = Vector3.Distance(player.position, tetherPoint);
isTethered = true;
}
} else if (isTethered && Input.GetKey(KeyCode.Space)) {
// this part does not
if (Vector3.Distance(player.position, tetherPoint) > tetherLength) {
player.position -= (Vector3.Distance(player.position, tetherPoint) - tetherLength) * (player.position - tetherPoint).normalized;
print((player.position - previousPlayerPosition).normalized);
player.gameObject.GetComponent<Rigidbody>().velocity = player.gameObject.GetComponent<Rigidbody>().velocity.magnitude * (player.position - previousPlayerPosition).normalized;
}
} else if (isTethered && !Input.GetKey(KeyCode.Space)) {
isTethered = false;
tetherPoint = Vector3.zero;
tetherObject = null;
currentTether = Vector3.zero;
tetherLength = 0;
}
if (tetherObject != null) {
if (currentTether != tetherObject.position) {
tetherPoint += currentTether - tetherObject.position;
currentTether = tetherObject.position;
}
}
previousPlayerPosition = player.position;```
i am trying to rotate object to 90 degrees smoothly on swipe here in my code its rotate instantly, how do i rotate object smoothly at given speed.
void Update()
{
if (fingerDown == false && Input.GetMouseButtonDown(0))
{
startPos = Input.mousePosition;
fingerDown = true;
}
if (fingerDown)
{
if (Input.mousePosition.x >= startPos.x + pixelDistToMove)
{
startPos = Input.mousePosition;
Vector3 rotationToAdd = new Vector3(0, 0, 90);
transform.Rotate(rotationToAdd);
fingerDown = false;
}
if (Input.mousePosition.x <= startPos.x - pixelDistToMove)
{
startPos = Input.mousePosition;
Vector3 rotationToAdd = new Vector3(0, 0, -90);
transform.Rotate(rotationToAdd);
fingerDown = false;
}
}
if (fingerDown && Input.GetMouseButtonUp(0))
{
fingerDown = false;
}
}
Thank you
transform.Rotate() rotates the object without animating it's rotation.
If you want it to rotate smoothly, you have to implement either an animation, or a turning state, or an IEnumerator.
My C# is a bit rusty, but I cooked this up:
public Vector3 desired_angle = Vector3.zero; // Turn the Gameobject to this angle
public float turn_time = 1f; // How long should turning take
public float rate = 60;
private void Update ()
{
if (Input.GetKeyDown(KeyCode.Space))
{
StartCoroutine(TurnTo());
}
}
IEnumerator TurnTo ()
{
Vector3 original_angle = transform.rotation.eulerAngles;
for (float i = 0f; i < 1f + turn_time / rate; i += turn_time / rate)
{
transform.rotation = Quaternion.Euler(Vector3.Lerp(original_angle, desired_angle, i));
yield return new WaitForSeconds(turn_time/rate);
}
}
I am developing an offline FPS multiplayer game.
When the Player Rotation value is (0,0,0), then Player moves perfectly in direction. However, my problem is when I rotate the camera using touch input. The player can also rotate his face and press the joystick button for moving the player, but then the player should not move the direction the camera is facing.
My Joystick Script For Player
public class VirtualJoystick : MonoBehaviour, IDragHandler, IPointerUpHandler,IPointerDownHandler {
private Image bgImg;
private Image JoyStickImage;
private Vector3 InputVector;
private void Start(){
bgImg = GetComponent<Image> ();
JoyStickImage = transform.GetChild (0).GetComponent<Image> ();
}
public virtual void OnDrag(PointerEventData ped){
Vector2 pos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle (bgImg.rectTransform, ped.position, ped.pressEventCamera, out pos)) {
pos.x = (pos.x / bgImg.rectTransform.sizeDelta.x);
pos.y = (pos.y / bgImg.rectTransform.sizeDelta.y);
InputVector = new Vector3 (pos.x * 2 + 1, 0, pos.y * 2 - 1);
InputVector = (InputVector.magnitude > 1) ? InputVector.normalized : InputVector;
JoyStickImage.rectTransform.anchoredPosition = new Vector3 (InputVector.x * (bgImg.rectTransform.sizeDelta.x / 2.5f),
InputVector.z * (bgImg.rectTransform.sizeDelta.y / 2.5f));
}
}
public virtual void OnPointerDown(PointerEventData ped){
OnDrag (ped);
}
public virtual void OnPointerUp(PointerEventData ped){
InputVector = Vector3.zero;
JoyStickImage.rectTransform.anchoredPosition = Vector3.zero;
}
public float Horizontal(){
if (InputVector.x != 0) {
return InputVector.x;
} else {
return Input.GetAxis ("Horizontal");
}
}
public float Vertical(){
if (InputVector.z != 0)
return InputVector.z;
else
return Input.GetAxis ("Vertical");
}
}
My Camera Rotation Script Using Input Touch
public class SwipeCam : MonoBehaviour {
private Vector3 firstPoint;
private Vector3 secondPoint;
private float xAngle = 0.0f;
private float yAngle = 0.0f;
private float xAngleTemp = 0.0f;
private float yAngleTemp = 0.0f;
void Start(){
xAngle = 0.0f;
yAngle = 0.0f;
this.transform.rotation = Quaternion.Euler (yAngle, xAngle, 0.0f);
}
void Update() {
if (Input.touchCount > 0) {
for (int i = 0; i < Input.touchCount; i++) {
Touch touch = Input.GetTouch (i);
if (touch.position.x > Screen.width / 2) {
if (touch.phase == TouchPhase.Began) {
firstPoint = Input.GetTouch (0).position;
xAngleTemp = xAngle;
yAngleTemp = yAngle;
}
if (touch.phase == TouchPhase.Moved) {
secondPoint = Input.GetTouch (0).position;
xAngle = xAngleTemp + (secondPoint.x - firstPoint.x) * 180.0f / Screen.width;
yAngle = yAngleTemp + (secondPoint.y - firstPoint.y) * 180.0f / -Screen.height;
yAngle = Mathf.Clamp (yAngle, -30f, 30f);
this.transform.rotation = Quaternion.Euler (yAngle, xAngle, 0.0f);
this.gameObject.GetComponentInParent<FPScontroller> ().transform.rotation = Quaternion.Euler (0.0f, xAngle, 0.0f);
//this.gameObject.GetComponentInParent<FPScontroller> ().transform.rotation = Quaternion.LookRotation(Vector3.forward,Vector3.up);
}
}
}
}
}
}
Where should I change my code to fix the facing the camera direction to player issue.
That is my Player Script (FPSController.cs)
public class FPScontroller : MonoBehaviour {
// Should this script respond to input?
public bool canControl = true;
public GameObject lookObj; //This is root object that containc MainCamera, Weapons etc.
public GameObject joystick;
bool useFixedUpdate = false;
//Check when run, walk or when can run or not
[HideInInspector]
public bool Running ;
[HideInInspector]
public bool Walking;
[HideInInspector]
public bool canRun;
[HideInInspector]
public Vector3 rorationDir;
//Ladder variables
private GameObject mainCamera = null;
[HideInInspector]
public bool onLadder = false;
//private float ladderHopSpeed = 6.0f;
// For the next variables, #System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
// Very handy for organization!
// The current global direction we want the character to move in.
[System.NonSerialized]
public Vector3 inputMoveDirection = Vector3.zero;
// Is the jump button held down? We use this interface instead of checking
// for the jump button directly so this script can also be used by AIs.
[System.NonSerialized]
public bool inputJump = false;
[HideInInspector]
public bool inputRun = false;
[HideInInspector]
public bool inputCrouch = false;
[HideInInspector]
public bool inputProne = false;
[System.Serializable]
public class FPScontrollerMovement {
// The maximum horizontal speed when moving
[HideInInspector]
public float maxForwardSpeed = 10.0f;
[HideInInspector]
public float maxSidewaysSpeed = 10.0f;
[HideInInspector]
public float maxBackwardsSpeed = 10.0f;
//Run and walk variables
public float WalkSpeed = 6.0f;
public float RunSpeed = 9.0f;
//Crouch
public bool canCrouch = true;
public float CrouchSpeed = 3.0f;
public float crouchHeight = 1.5f;
public float crouchSmooth = 8;
//prone
public bool canProne = true;
public float ProneSpeed = 1.5f;
public float proneHeight = 0.7f;
// Curve for multiplying speed based on slope (negative = downwards)
public AnimationCurve slopeSpeedMultiplier = new AnimationCurve(new Keyframe(-90, 1), new Keyframe(0, 1), new Keyframe(90, 0));
// How fast does the character change speeds? Higher is faster.
public float maxGroundAcceleration = 30.0f;
public float maxAirAcceleration = 20.0f;
// The gravity for the character
public float gravity = 10.0f;
public float maxFallSpeed = 20.0f;
[HideInInspector]
public bool enableGravity = true;
// For the next variables, #System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
// Very handy for organization!
// The last collision flags returned from controller.Move
[System.NonSerialized]
public CollisionFlags collisionFlags;
// We will keep track of the character's current velocity,
[System.NonSerialized]
public Vector3 velocity;
// This keeps track of our current velocity while we're not grounded
[System.NonSerialized]
public Vector3 frameVelocity = Vector3.zero;
[System.NonSerialized]
public Vector3 hitPoint = Vector3.zero;
[System.NonSerialized]
public Vector3 lastHitPoint = new Vector3(Mathf.Infinity, 0, 0);
}
public FPScontrollerMovement movement = new FPScontrollerMovement();
void Awake () {
if (GetComponent<NetworkView> ().isMine) {
joystick = GameObject.Find ("Joystick");
controller = gameObject.GetComponent<CharacterController>();
standartHeight = controller.height;
/*if(GameObject.FindWithTag("LookObject") != null){
lookObj = GameObject.FindWithTag("LookObject");
}*/
centerY = controller.center.y;
tr = transform;
canRun = true;
canStand = true;
StartCoroutine(setupBools());
}
}
void Update () {
if (GetComponent<NetworkView> ().isMine) {
if (!useFixedUpdate) {
UpdateFunction ();
}
movement.velocity.x = joystick.GetComponent<VirtualJoystick> ().Horizontal () * 5f;
movement.velocity.z = joystick.GetComponent<VirtualJoystick> ().Vertical () * 5f;
//Run input
if (Input.GetAxis ("Vertical") > 0.1f && inputRun && canRun && !onLadder && Walking) {
if (canStand && canStandCrouch) {
OnRunning ();
}
} else {
OffRunning ();
}
//Check when walk or not
if ((movement.velocity.x > 0.01f || movement.velocity.z > 0.01f) || (movement.velocity.x < -0.01f || movement.velocity.z < -0.01f)) {
RunAnimation1 ();
Debug.Log ("Forward");
Walking = true;
}else if (movement.velocity.x > 0.01f) {
Walking = true;
Debug.Log ("Right");
} else if (movement.velocity.x < -0.01f) {
Walking = true;
Debug.Log ("Left");
} else {
RunAnimation ();
Walking = false;
}
if (!canControl)
return;
if (movement.canCrouch) {
if (!onLadder) {
Crouch ();
}
}
if (movement.canProne) {
if (!onLadder) {
Prone ();
}
}
if (onLadder) {
grounded = false;
crouch = false;
prone = false;
}
if (!crouch && !prone && controller.height < standartHeight - 0.01f) {
controller.height = Mathf.Lerp (controller.height, standartHeight, Time.deltaTime / movement.crouchSmooth);
controller.center = new Vector3 (controller.center.x, Mathf.Lerp (controller.center.y, centerY, Time.deltaTime / movement.crouchSmooth), controller.center.z);
lookObj.transform.localPosition = new Vector3 (lookObj.transform.localPosition.x, Mathf.Lerp (lookObj.transform.localPosition.y, standartHeight, Time.deltaTime / movement.crouchSmooth), lookObj.transform.localPosition.z);
}
}
}
void RunAnimation(){
GetComponent<NetworkView> ().RPC ("SysnAnimation", RPCMode.All, 0);
}
void RunAnimation1(){
GetComponent<NetworkView> ().RPC ("SysnAnimation", RPCMode.All, 1);
}
void RunAnimation2(){
GetComponent<NetworkView> ().RPC ("SysnAnimation", RPCMode.All, 2);
}
[RPC]
void SysnAnimation(int index){
if (index == 0) {
GetComponent<Animator> ().Play ("Idle Aim");
} else if (index == 1) {
GetComponent<Animator> ().Play ("Walk Aiming");
} else if (index == 2) {
GetComponent<Animator> ().Play ("Jump");
}
}
void OnRunning (){
Debug.Log ("Run");
Running = true;
movement.maxForwardSpeed = movement.RunSpeed;
movement.maxSidewaysSpeed = movement.RunSpeed;
//Make bigger extra height when player run to increase jump distance
jumping.extraHeight = jumping.baseHeight + 0.15f;
}
void OffRunning (){
Running = false;
if(crouch || prone)
return;
movement.maxForwardSpeed = movement.WalkSpeed;
movement.maxSidewaysSpeed = movement.WalkSpeed;
movement.maxBackwardsSpeed = movement.WalkSpeed/2;
//Change extraheight value to default when player walk
jumping.extraHeight = jumping.baseHeight;
}}
Your camera and joystick code looks fine, but that's not where the problem is.
I'll assume your player movement code looks something like this:
Get input X and Y
Move player right by X, forward by Y
In code form, that might look something like this:
//returns the world-space direction that player wants to move
Vector3 GetDesiredMovement(float inputForward, float inputRight) {
//get a vector pointing to player's right
Vector3 dirRight = Camera.main.transform.right;
dirRight.y = 0f;
dirRight.Normalize();
//get a vector pointing to player's front
Vector3 dirForward = Camera.main.transform.forward;
dirForward.y = 0f;
dirForward.Normalize();
//calculate desired movement based on input
Vector3 desiredMovement = (dirForward * inputForward) + (dirRight * inputRight);
desiredMovement.Normalize();
return desiredMovement;
}
What if "right" and "forward" need to be relative to some other object in the scene, such as a camera? It's easier than you might think: just read those values directly from the camera's transform component.
You could do that by replacing just two lines from the above example:
Vector3 dirRight = Camera.main.transform.right;
Vector3 dirForward = Camera.main.transform.forward;
I solved the problem of basing player movement of the camera's direction.
In my Player's script there are two lines that read joystick input:
movement.velocity.x = joystick.GetComponent<VirtualJoystick> ().Horizontal () * 5f;
movement.velocity.z = joystick.GetComponent<VirtualJoystick> ().Vertical () * 5f;`
I changed them to this:
Vector3 DirectionVector =
new Vector3 (joystick.GetComponent<VirtualJoystick> ().Horizontal (), 0f, joystick.GetComponent<VirtualJoystick> ().Vertical ());
movement.velocity = transform.rotation * DirectionVector * 10f;
Directly add joystick value in movement vector. I just multiply it to the joystick input vector and solve my problem.
Now the player moves based on the player rotation and where the camera is facing.
Thanks everyone for help.
Here is my code:
public class CharacterController : MonoBehaviour
{
private Vector3 _startLocation = Vector3.zero;
private Vector3 _currentLocation = Vector3.zero;
private Vector3 _endLocation = Vector3.zero;
private bool _isMoving = false;
private float _distanceToTravel;
private float _startTime;
public float Speed = 1.0f;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log("Left mouse button clicked");
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.gameObject.CompareTag("Ground"))
{
_startLocation = transform.position;
_endLocation = hit.point;
_isMoving = true;
_startTime = Time.time;
_distanceToTravel = Vector3.Distance(_startLocation, _endLocation);
Debug.Log(string.Format("Ground has been hit: Start: {0}, End: {1}", _startLocation.ToString(), _endLocation.ToString()));
}
}
}
if (_isMoving)
Move();
}
void Move()
{
float timeElapsed = (Time.time - _startTime) * Speed;
float t = timeElapsed / _distanceToTravel;
_currentLocation = Vector3.Lerp(_startLocation, _endLocation, t);
transform.Translate(_currentLocation);
if (_currentLocation == _endLocation)
{
Debug.Log(string.Format("Destination reached ({0})", _endLocation.ToString()));
_isMoving = false;
}
}
}
I read the documentation on the Vector3.Lerp function, as well as the Physics.Raycast function, and ended up with this code.
The debug console confirms that the Ground has been hit, but my capsule starts moving upwards in the Y direction and never stops!
I'm still very new to Unity and game development in general, so I'm still learning, but any pointers on what I'm doing wrong?
it is moving in the Y because you use transform.Translate.
transform.Translate is moving it, so if you did transform.Translate(0, 0, 10)
it would move in the z, and if you did transform.Translate(0, 10, 10)
it will move in the y and z direction.
So to fix this i will show you 2 ways:
1) Using Vector3.Lerp:
transform.position = Vector3.Lerp(_startLocation, _endLocation, t);
2) Using MoveTowards:
transform.position = Vector3.MoveTowards(transform.position, _endLocation, Speed * Time.deltaTime);
In the first Vector3.Lerp is used, and i see you use it too
_currentLocation = Vector3.Lerp(_startLocation, _endLocation, t);
So you could do either this:
transform.position = Vector3.Lerp(_startLocation, _endLocation, t);
or this
transform.position = _currentLocation;
Both will do the same because you assigned _currentLocation to
Vector3.Lerp(_startLocation, _endLocation, t);
And you can read about MoveTowards here
http://docs.unity3d.com/ScriptReference/Vector3.MoveTowards.html
Check the Comments line You will understand what I had edited to bring the Solution.
It works well for me
void Start()
{
_startLocation = transform.position; // Changed Here to Initialize once
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log("Left mouse button clicked");
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.gameObject.CompareTag("Ground"))
{
print(hit.point);
//**Here you mentioned _StartLocation = transform.position
//this instantly changes the starting point Every time so
//if SP changes then totally changed in Translation.***
_endLocation= hit.point;
_isMoving = true;
_startTime = Time.time;
_distanceToTravel = Vector3.Distance(_startLocation, _endLocation);
}
}
}
if (_isMoving)
{
Move();
}
}
void Move()
{
float timeElapsed = (Time.time - _startTime) * Speed;
float t = timeElapsed / _distanceToTravel;
_currentLocation = Vector3.Lerp(_startLocation, _endLocation, t);
transform.position = Vector3.Lerp(_startLocation, _endLocation, t);
_startLocation = _endLocation;
//*** This line is for Next Mouse
//click. So every next click StartPoint is Current Click
//EndPoint***
if (_currentLocation == _endLocation)
{
Debug.Log(string.Format("Destination reached ({0})", _endLocation.ToString()));
_isMoving = false;
}
}
}
I need your help.
I make a Hover-car movement script.
Distance to ground and the Hover movement is calculated by Raycast,
I make another Raycast, because there was a problem - hover flew too high if you hold the button pressed.
But now with two Raycast it cause a lag - Hover moves in jerks.
Interpolate does not help.
How can I make smooth movement without jerking?
Please, help.
public class hoverController_v7 : MonoBehaviour
Rigidbody carBody;
float deadZone = 0.1f;
public float hoverForce = 9.0f;
public float hoverHeight = 2.0f;
public GameObject[] hoverPoints;
public float forwardAcceleration = 100.0f;
public float backwardAcceleration = 25.0f;
public float currThrust = 0.0f;
public float turnStrength = 10.0f;
public float currTurn = 0.0f;
public GameObject leftAirBrake;
public GameObject rightAirBrake;
int layerMask;
void Start()
{
carBody = GetComponent<Rigidbody>();
layerMask = 1 << LayerMask.NameToLayer("Characters");
layerMask = ~layerMask;
}
void OnDrawGizmos()
{
// сила hoverForce
RaycastHit hit;
for(int i = 0; i < hoverPoints.Length; i++)
{
var hoverPoint = hoverPoints[i];
if(Physics.Raycast(hoverPoint.transform.position,
-Vector3.up, out hit,
hoverHeight,
layerMask))
{
Gizmos.color = Color.yellow;
//Color if correctly alligned
Gizmos.DrawLine(hoverPoint.transform.position, hit.point);
Gizmos.DrawSphere(hit.point, 0.5f);
}
else
{
Gizmos.color = Color.red;
//Color if incorrectly alligned
Gizmos.DrawLine (hoverPoint.transform.position, hoverPoint.transform.position - Vector3.up * hoverHeight);
}
}
}
void Update()
{
// main thrust
currThrust = 0.0f;
float aclAxis = Input.GetAxis("Vertical");
if(aclAxis > deadZone)
{
currThrust = aclAxis * forwardAcceleration;
}
else if(aclAxis < -deadZone)
{
currThrust = aclAxis * backwardAcceleration;
}
// Turning
currTurn = 0.0f;
float turnAxis = Input.GetAxis("Mouse X") * 2;
if(Mathf.Abs(turnAxis) > deadZone)
currTurn = turnAxis;
}
void FixedUpdate()
{
// hover force
RaycastHit hit;
for(int i = 0; i < hoverPoints.Length; i++)
{
var hoverPoint = hoverPoints[i];
if(Physics.Raycast(hoverPoint.transform.position,
-Vector3.up, out hit,
hoverHeight, layerMask))
carBody.AddForceAtPosition(Vector3.up * hoverForce * (1.0f -(hit.distance / hoverHeight)),
hoverPoint.transform.position);
else
{
if(transform.position.y > hoverPoint.transform.position.y)
carBody.AddForceAtPosition(hoverPoint.transform.up * hoverForce, hoverPoint.transform.position);
else
//add force to car
carBody.AddForceAtPosition(hoverPoint.transform.up * -hoverForce, hoverPoint.transform.position);
}
}
// forward
RaycastHit hit2;
if(Physics.Raycast(transform.position, -transform.up, out hit2))
{
if(hit2.distance < 2)
{
if(Mathf.Abs(currThrust) > 0)
{
carBody.AddForce(transform.forward * currThrust);
}
}
}
// turn
if(currTurn > 0)
{
carBody.AddRelativeTorque(Vector3.up * currTurn * turnStrength);
}
else if(currTurn < 0)
{
carBody.AddRelativeTorque(Vector3.up * currTurn * turnStrength);
}
}
}
You need to rethink your game's logic. Raycasts are computationally expensive. You are firing two on the FixedUpdate(). Then you have have a for loop inside that update, which is generally a bad idea.
If you really need to know the distance to the ground fire a raycast on the Update() instead.