Seek algorithm for cars - c#

I am trying to implement the seek algorithm of steering behaviors for cars. The way I have defined a path for the cars is by using spheres to signify waypoints.
I want the car to move along this waypoint using the seek algorithm. I am trying to do it in the following way. However, the car will only go to the first waypoint and get stuck there.
More specifically, my problem is that my implementation won't update wayIndex and this causes the target to never go to the next point in the waypoints array.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Follower : MonoBehaviour
{
public GameObject vehicle;
public float[] speeds = {15.0f,25.0f,35.0f};
public int pathChoice;
[SerializeField]
public Transform[] waypoints;
public Transform[] waypoints2;
[SerializeField]
public float speed;
private int wayIndex = 0;
private Vector3 target;
private Vector3 steering;
private void Start(){
int speedIndex = UnityEngine.Random.Range(0, 3);
int pathIndex = UnityEngine.Random.Range(0, 2);
speed = speeds[speedIndex];
pathChoice = pathIndex;
if (pathIndex == 0){
steering = Vector3.zero;
target = waypoints[wayIndex].position;
transform.position = waypoints[wayIndex].transform.position;
}else if (pathIndex == 1){
steering = Vector3.zero;
target = waypoints2[wayIndex].position;
transform.position = waypoints2[wayIndex].transform.position;
}
}
private void Update(){
MoveVehicle();
// transform.Rotate(-90f,0,0,Space.Self);
}
private void MoveVehicle(){
if (pathChoice == 0){
if (wayIndex <= waypoints.Length - 1){
target = waypoints[wayIndex].position;
Vector3 velocity = (target - transform.position).normalized * speed;
Vector3 seekForce = seek(target);
steering = steering + seekForce;
Vector3 finalVel = (velocity + steering);
// transform.position = Vector3.MoveTowards(transform.position,target,speed * Time.deltaTime);
transform.position = transform.position + finalVel * Time.deltaTime;
transform.LookAt(target);
// var targetRotation = Quaternion.LookRotation(target- transform.position);
// transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
if (transform.position == waypoints[wayIndex].transform.position){
wayIndex += 1;
}
if (transform.position == waypoints[waypoints.Length - 1].position){
speed = 0.0f;
}
}
}else if (pathChoice == 1){
if (wayIndex <= waypoints2.Length - 1){
target = waypoints2[wayIndex].position;
transform.position = Vector3.MoveTowards(transform.position,target,speed * Time.deltaTime);
// var targetRotation = Quaternion.LookRotation(target- transform.position);
// transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
transform.LookAt(target);
if (transform.position == waypoints2[wayIndex].transform.position){
wayIndex += 1;
}
if (transform.position == waypoints2[waypoints2.Length - 1].position){
speed = 0.0f;
vehicle.GetComponent<Follower>().enabled = false;
vehicle.GetComponent<Collisions>().enabled = false;
Destroy(vehicle);
}
}
}
}
private Vector3 seek(Vector3 target){
Vector3 vel = (target - transform.position).normalized * speed;
Vector3 desiredVel = (target - transform.position).normalized * speed;
Vector3 steeringForce = desiredVel - vel;
return steeringForce;
}
}

Two issues I see
You are moving your object using
transform.position = transform.position + finalVel * Time.deltaTime;
So it might happen that this overshoots the target so the check
if (transform.position == waypoints[wayIndex].transform.position)
which uses a precision range of 0.00001 never becomes true.
Before this didn't happen because MoveTowards prevents any overshooting.
You will need to use a certain range and rather approximately check
if(Vector3.Distance(transform.position, waypoints[wayIndex].transform.position) <= THRESHOLD)
where THRESHOLD needs to be a range big enough to not to be overshooten by finalVel => Something greater than the maximum finalVel magnitude
In
Vector3 vel = (target - transform.position).normalized * speed;
Vector3 desiredVel = (target - transform.position).normalized * speed;
Vector3 steeringForce = desiredVel - vel;
you store and substract the exact same vector .. your steeringForce is doomed to be always 0,0,0!

Related

Smooth movement using joystick in Unity3D

I try to accomplish smooth movement with the Xbox Controller, however it is very snappy, even though snap is turned of and deadzone set to 0. Movement with keyboard however is very smooth, so I assume GetAxis does not work with a controller, it's always GetAxisRaw. So I switched to GetAxisRaw and tried to smooth everything out. Even with acceleration, the movement is still very jagged and snappy. Does anyone have an idea how to get a nice smooth movement with a controller, like keyboard + GetAxis?
public class PlayerController : MonoBehaviour
{
CharacterController cc;
float acceleration = 0;
[SerializeField] float speed;
[SerializeField] float acclerationRate = 1;
private void Awake()
{
cc = GetComponent<CharacterController>();
}
private void Update()
{
float deadzone = 0f;
Vector2 stickInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
if (stickInput.magnitude < deadzone)
stickInput = Vector2.zero;
else
stickInput = stickInput.normalized * ((stickInput.magnitude - deadzone) / (1 - deadzone));
if (stickInput.x != 0 || stickInput.y != 0)
{
acceleration += Time.deltaTime * acclerationRate;
acceleration = Mathf.Clamp01(acceleration);
}
else
{
acceleration = 0;
}
cc.Move(new Vector3(stickInput.x, 0, stickInput.y) * speed * acceleration * Time.deltaTime);
}
}
I would keep track of your player's velocity and use MoveTowards to adjust it based on the input. Don't forget to clamp your input's magnitude so your character doesn't travel diagonally faster than orthogonally in the event the player prefers keyboard input.
CharacterController cc;
[SerializeField] float speed;
[SerializeField] float acclerationRate = 1;
[SerializeField] float deadzone = 0f;
Vector3 velocity;
private void Awake()
{
cc = GetComponent<CharacterController>();
velocity = Vector3.zero;
}
private void Update()
{
Vector3 stickInput = new Vector3(Input.GetAxisRaw("Horizontal"), 0f,
Input.GetAxisRaw("Vertical"));
if (stickInput.magnitude < deadzone)
}
stickInput = Vector3.zero;
}
else
{
float clampedMag = Mathf.Min(1f, stickInput.magnitude);
stickInput = stickInput.normalized * (clampedMag - deadzone) / (1f - deadzone);
}
velocity = Vector3.MoveTowards(velocity, stickInput,
accelerationRate * Time.deltaTime);
cc.Move(velocity * Time.deltaTime);
}

Unity rigidbody collision not working properly

Im having a lot of weird prolems with my rigidbody collision in unity. I have a player controller script which allows me to move my player, but when it collides with stairs, it glitches out. when it collides with a door, it glitches out and when it collides with 2 nvisible box colliders at the edge of the map while walking diagonally, it walks through one of them. Ive searched around quite a bit but couldn't find anything. I know it's not a lot to go on, but here is some stuff that might help:
a video of what happens exactly
the character controller code:
using System;
using UnityEngine;
public class PlayerController : MonoBehaviour{
public Rigidbody body;
//player movement
private float speed = 12f;
private float walkSpeed = 10;
private float runSpeed = 15;
private float gravity = -9.81f;
public float jumpHeight = 2f;
private Vector3 inputs;
//player rotation
private float targetAngle = 0f;
private float angle = 0f;
public float turnSmoothTime = .1f;
public float turnSmoothVelocity;
//player jump
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
private bool isGrounded;
//there are 6 possible directions for gravity; positive and negative x, y and z. The direction can therefore be -3, -2, -1, 1, 2 or 3 where 1=y, 2=x, 3=z
public int direction = 1;
public void movePlayer(Vector2 movement){
float horizontal = movement.x;
float vertical = movement.y;
//check if the player is standing on the ground
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
Quaternion rotation = new Quaternion();
body.freezeRotation = true;
if (Mathf.Abs(direction) == 1){
//gravity in y direction
//set the direction of the gravity
Physics.gravity = new Vector3(0f, direction * gravity, 0f);
//set the direction the inputs should work in
inputs.x = horizontal;
inputs.z = vertical;
inputs.y = body.velocity.y;
//calculate the angle with which the player has to be rotated and make the rotation smooth (smoothing is only possible in this orientation)
targetAngle = Mathf.Atan2(inputs.x, inputs.z) * Mathf.Rad2Deg;
angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
//set the characters rotation
rotation = Quaternion.Euler(0f, angle, 0f);
}
else if (Mathf.Abs(direction) == 2){
//gravity in x direction
Physics.gravity = new Vector3((direction / 2) * gravity, 0f, 0f);
inputs.y = -horizontal;
inputs.z = vertical;
inputs.x = body.velocity.x;
targetAngle = Mathf.Atan2(-inputs.y, inputs.z) * Mathf.Rad2Deg;
rotation = Quaternion.Euler(targetAngle, 0f, (direction / 2) * -90f);
}
else if (Mathf.Abs(direction) == 3){
//gravity in z-direction
Physics.gravity = new Vector3(0f, 0f, (direction / 3) * -gravity);
inputs.x = horizontal;
inputs.y = vertical;
inputs.z = body.velocity.z;
targetAngle = Mathf.Atan2(inputs.x, inputs.y) * Mathf.Rad2Deg;
//set the rotation in the correct order of the axis (90 degrees first and then around the correct axis)
rotation = Quaternion.AngleAxis((direction / 3) * -90f, Vector3.right) *
Quaternion.AngleAxis(0f, Vector3.forward) *
Quaternion.AngleAxis(targetAngle, Vector3.up);
}
else{
direction = 1;
}
/*
if (inputs != Vector3.zero){
body.velocity = inputs;
}*/
//rotate the player in the move direction as long as they are moving
if (inputs.magnitude >= 0.1f){
transform.rotation = rotation;
}
}
void FixedUpdate(){
//move the player
body.MovePosition(body.position + inputs * speed * Time.fixedDeltaTime);
}
public void flip(int changedDirection){
inputs = Vector3.zero;
angle = 0f;
targetAngle = 0f;
direction = changedDirection;
}
public void walk(){
if (isGrounded){
speed = walkSpeed;
}
}
public void run(){
if (isGrounded){
speed = runSpeed;
}
}
public void jump(){
if (isGrounded){
if (direction == 1){
body.velocity = new Vector3(inputs.x, jumpHeight, inputs.z);
}
else if (direction == 2){
body.velocity = new Vector3(jumpHeight, inputs.y, inputs.z);
}
else if (direction == 3){
body.velocity = new Vector3(inputs.x, inputs.y, jumpHeight);
}
}
}
}
A screenshot of my player object's important components:
P.S. the code has some weird gravty changing parts. Thats for the rest of the game, but it's not important for this question. Hopefully you guys can help me. Im happy to provide any other information you might need :) thanks for your time in advance!!
Edit: Commented out one part based on the first answer, but that din't fix it
First of all, you move your player 'twice', first inside movePlayer function you have:
//move the player
if (inputs != Vector3.zero){
body.velocity = inputs;
}
and then in every FixedUpdate:
body.MovePosition(body.position + inputs * speed * Time.fixedDeltaTime);
body.MovePosition moves yours player, but not zeroes velocity (which you set in movePlayer function).
By moving player this way you can 'overshoot' too small colider, so object will pass through.
You can add more drag to rigidbody to slowdown object a bit.
Okay so for anyone having similar problems, I found the answer:
The problem was that I was using body.moveposition, this should actually body.addforce.
This oes mean that you have to change some of the code. If you want further explanation because you had a similar problem, contact me, but here is my improved code to get you started:
using System;
using UnityEngine;
public class PlayerController : MonoBehaviour{
public Rigidbody body;
//player movement
private float speed = 12f;
private float walkSpeed = 10;
private float runSpeed = 15;
public float gravity = -9.81f;
public float jumpHeight = 2f;
private Vector3 inputs;
//player rotation
private float targetAngle = 0f;
private float angle = 0f;
public float turnSmoothTime = .1f;
public float turnSmoothVelocity;
//player jump
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
private bool isGrounded;
//there are 6 possible directions for gravity; positive and negative x, y and z. The direction can therefore be -3, -2, -1, 1, 2 or 3 where 1=y, 2=x, 3=z
public int direction = 1;
public void movePlayer(Vector2 movement){
float horizontal = movement.x;
float vertical = movement.y;
//check if the player is standing on the ground
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
Quaternion rotation = new Quaternion();
body.freezeRotation = true;
if (Mathf.Abs(direction) == 1){
//gravity in y direction
//set the direction of the gravity
Physics.gravity = new Vector3(0f, direction * gravity, 0f);
//set the direction the inputs should work in
inputs.x = horizontal;
inputs.z = vertical;
inputs.y = 0;
//calculate the angle with which the player has to be rotated and make the rotation smooth (smoothing is only possible in this orientation)
targetAngle = Mathf.Atan2(inputs.x, inputs.z) * Mathf.Rad2Deg;
angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
//set the characters rotation
rotation = Quaternion.Euler(0f, angle, 0f);
}
else if (Mathf.Abs(direction) == 2){
//gravity in x direction
Physics.gravity = new Vector3((direction / 2) * gravity, 0f, 0f);
inputs.y = -horizontal;
inputs.z = vertical;
inputs.x = body.velocity.x;
targetAngle = Mathf.Atan2(-inputs.y, inputs.z) * Mathf.Rad2Deg;
rotation = Quaternion.Euler(targetAngle, 0f, (direction / 2) * -90f);
}
else if (Mathf.Abs(direction) == 3){
//gravity in z-direction
Physics.gravity = new Vector3(0f, 0f, (direction / 3) * -gravity);
inputs.x = horizontal;
inputs.y = vertical;
inputs.z = body.velocity.z;
targetAngle = Mathf.Atan2(inputs.x, inputs.y) * Mathf.Rad2Deg;
//set the rotation in the correct order of the axis (90 degrees first and then around the correct axis)
rotation = Quaternion.AngleAxis((direction / 3) * -90f, Vector3.right) *
Quaternion.AngleAxis(0f, Vector3.forward) *
Quaternion.AngleAxis(targetAngle, Vector3.up);
}
else{
direction = 1;
}
//rotate the player in the move direction as long as they are moving
if (inputs.magnitude >= 0.1f){
transform.rotation = rotation;
}
}
void FixedUpdate(){
body.AddForce(inputs * speed * Time.fixedDeltaTime);
}
public void flip(int changedDirection){
inputs = Vector3.zero;
angle = 0f;
targetAngle = 0f;
direction = changedDirection;
}
public void walk(){
if (isGrounded){
speed = walkSpeed;
}
}
public void run(){
if (isGrounded){
speed = runSpeed;
}
}
public void jump(){
if (isGrounded){
if (direction == 1){
body.AddForce(new Vector3(0, jumpHeight, 0));
}
else if (direction == 2){
body.AddForce(new Vector3(jumpHeight, 0, 0));
}
else if (direction == 3){
body.AddForce(new Vector3(0,0 , jumpHeight));
}
}
}
}
For me this created some additionl problems with jump for example, so here are the values you need to tweak to fix those: the rigidbody mass and drag and the player controller gravity and jump height.

Unity3d bunny hopping controller. My velocity decreases when I'm strafing fast

I created a FPS Movement script in unity3d for bunny hopping with references from there, but I have some issues.When I am strafing fast my speed decreases.
I wanted to create something like this
This is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour {
//Strafe Variables
public float gravity = 3f;
public float ground_accelerate = 50f;
public float max_velocity_ground = 4f;
public float air_accelerate = 150f;
public float max_velocity_air = 2f;
public float friction = 8;
bool onGround;
public float jump_force = 5f;
private Vector3 lastFrameVelocity = Vector3.zero;
public Camera camObj;
Rigidbody rb;
Collider coll;
void Start () {
rb = GetComponent<Rigidbody> ();
coll = GetComponent<Collider> ();
}
void Update () {
Vector2 input = new Vector2 (Input.GetAxis ("Horizontal"), Input.GetAxis ("Vertical"));
Vector3 tempVelocity = CalculateFriction(rb.velocity);
tempVelocity += CalculateMovement (input, tempVelocity);
rb.velocity = tempVelocity;
lastFrameVelocity = rb.velocity;
rb.velocity += new Vector3(0f,-gravity,0f) * Time.deltaTime;
}
public Vector3 CalculateFriction(Vector3 currentVelocity)
{
onGround = Grounded();
float speed = currentVelocity.magnitude;
//Code from https://flafla2.github.io/2015/02/14/bunnyhop.html
if (!onGround || Input.GetButton("Jump") || speed == 0f)
return currentVelocity;
float drop = speed * friction * Time.deltaTime;
return currentVelocity * (Mathf.Max(speed - drop, 0f) / speed);
}
//Do movement input here
public Vector3 CalculateMovement(Vector2 input, Vector3 velocity)
{
onGround = Grounded();
//Different acceleration values for ground and air
float curAccel = ground_accelerate;
if (!onGround)
curAccel = air_accelerate;
//Ground speed
float curMaxSpeed = max_velocity_ground;
//Air speed
if (!onGround)
curMaxSpeed = max_velocity_air;
//Get rotation input and make it a vector
Vector3 camRotation = new Vector3(0f, camObj.transform.rotation.eulerAngles.y, 0f);
Vector3 inputVelocity = Quaternion.Euler(camRotation) *
new Vector3(input.x * air_accelerate, 0f, input.y * air_accelerate);
//Ignore vertical component of rotated input
Vector3 alignedInputVelocity = new Vector3(inputVelocity.x, 0f, inputVelocity.z) * Time.deltaTime;
//Get current velocity
Vector3 currentVelocity = new Vector3(velocity.x, 0f, velocity.z);
//How close the current speed to max velocity is (1 = not moving, 0 = at/over max speed)
float max = Mathf.Max(0f, 1 - (currentVelocity.magnitude / curMaxSpeed));
//How perpendicular the input to the current velocity is (0 = 90°)
float velocityDot = Vector3.Dot(currentVelocity, alignedInputVelocity);
//Scale the input to the max speed
Vector3 modifiedVelocity = alignedInputVelocity*max;
//The more perpendicular the input is, the more the input velocity will be applied
Vector3 correctVelocity = Vector3.Lerp(alignedInputVelocity, modifiedVelocity, velocityDot);
//Apply jump
correctVelocity += GetJumpVelocity(velocity.y);
//Return
return correctVelocity;
}
private Vector3 GetJumpVelocity(float yVelocity)
{
Vector3 jumpVelocity = Vector3.zero;
//Calculate jump
if ( Input.GetButton("Jump") && yVelocity < jump_force && Grounded())
{
jumpVelocity = new Vector3(0f, jump_force - yVelocity, 0f);
}
return jumpVelocity;
}
bool Grounded(){
return Physics.Raycast (transform.position, Vector3.down, coll.bounds.extents.y + 0.1f);
}
}

How to move 2D Object with WASD in Unity

My code below only works for horizontal movement. Shouldn't the vertical movement be working too? I'm just starting out with basic 2D Unity programming:
public class Player : MonoBehaviour {
//These fields will be exposed to Unity so the dev can set the parameters there
[SerializeField] private float speed = 1f;
[SerializeField] private float upY;
[SerializeField] private float downY;
[SerializeField] private float leftX;
[SerializeField] private float rightX;
private Transform _transformY;
private Transform _transformX;
private Vector2 _currentPosY;
private Vector2 _currentPosX;
// Use this for initialization
void Start () {
_transformY = gameObject.GetComponent<Transform> ();
_currentPosY = _transformY.position;
_transformX = gameObject.GetComponent<Transform> ();
_currentPosX = _transformX.position;
}
// Update is called once per frame
void Update () {
_currentPosY = _transformY.position;
_currentPosX = _transformX.position;
float userInputV = Input.GetAxis ("Vertical");
float userInputH = Input.GetAxis ("Horizontal");
if (userInputV < 0)
_currentPosY -= new Vector2 (0, speed);
if (userInputV > 0)
_currentPosY += new Vector2 (0, speed);
if (userInputH < 0)
_currentPosX -= new Vector2 (speed, 0);
if (userInputH > 0)
_currentPosX += new Vector2 (speed, 0);
CheckBoundary ();
_transformY.position = _currentPosY;
_transformX.position = _currentPosX;
}
private void CheckBoundary(){
if (_currentPosY.y < upY)
_currentPosY.y = upY;
if (_currentPosY.y > downY)
_currentPosY.y = downY;
if (_currentPosX.x < leftX)
_currentPosX.x = leftX;
if (_currentPosX.x > rightX)
_currentPosX.x = rightX;
}
}
If I remove/comment out the _currentPosX and it's related codes then my Vertical movement works. But if I remove/comment out the _currentPosY and it's related codes then my Horizontal movement works.
But how come I'm having trouble getting them to work at the same time? I think I'm just missing something but I can't figure it out since I'm just a beginner at this.
Thanks to whoever can give advise.
EDIT: for further clarification...
I'm coding a simple 2d game that will have the player move in 4-directions using the WASD keys.
W = move up
A = move left
S = move down
D = move right
My main problem is that I can get two of the keys working only in one axis: either A and D is working for Horizontal while W and S are not working at all for Vertical movement or vice-versa.
You don't need those if statements. Just use += to append the input to the current transform position.
Move without Rigidbody:
public float speed = 100;
public Transform obj;
public void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 tempVect = new Vector3(h, v, 0);
tempVect = tempVect.normalized * speed * Time.deltaTime;
obj.transform.position += tempVect;
}
Move Object with Rigidbody2D:
public float speed = 100;
public Rigidbody2D rb;
public void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 tempVect = new Vector3(h, v, 0);
tempVect = tempVect.normalized * speed * Time.deltaTime;
rb.MovePosition(rb.transform.position + tempVect);
}
I suggest using the second code and moving the Rigidbody if you want to be able to detect collison later on.
Note:
You must assign the object to move to the obj slot in the Editor. If using the second code, assign the object with the Rigidbody2D to the rb slot in the Editor.
THIS CODE WORK 100% (you must try it.)
public float moveSpeed = 5;
void Start()
{
}
void Update()
{
if (Input.GetKey(KeyCode.D))
{
transform.position += Vector3.right * moveSpeed * Time.deltaTime;
}
else if (Input.GetKey(KeyCode.A))
{
transform.position += Vector3.right * -moveSpeed * Time.deltaTime;
}
else if (Input.GetKey(KeyCode.W))
{
transform.position += Vector3.up * moveSpeed * Time.deltaTime;
}
else if (Input.GetKey(KeyCode.S))
{
transform.position += Vector3.up * -moveSpeed * Time.deltaTime;
}
}
Try changing the value 0 in the Vector2 functions to current x/ y position...I ran into a similar problem with my project
if (userInputV < 0)
_currentPosY -= new Vector2 (/*current position*/, speed);

How to stop camera following Y in unity

I have this code and I can't figure out how to make the camera stop following my player when he jumps, in unity3d
using UnityEngine;
using System.Collections;
public class Camera2DFollow2 : MonoBehaviour {
public Transform target;
public float damping = 1;
public float lookAheadFactor = 3;
public float lookAheadReturnSpeed = 0.5f;
public float lookAheadMoveThreshold = 0.1f;
float offsetZ;
Vector3 lastTargetPosition;
Vector3 currentVelocity;
Vector3 lookAheadPos;
// Use this for initialization
void Start () {
lastTargetPosition = target.position;
offsetZ = (transform.position - target.position).z;
transform.parent = null;
}
// Update is called once per frame
void Update () {
// only update lookahead pos if accelerating or changed direction
float xMoveDelta = (target.position - lastTargetPosition).x;
bool updateLookAheadTarget = Mathf.Abs(xMoveDelta) > lookAheadMoveThreshold;
if (updateLookAheadTarget) {
lookAheadPos = lookAheadFactor * Vector3.right * Mathf.Sign(xMoveDelta);
} else {
lookAheadPos = Vector3.MoveTowards(lookAheadPos, Vector3.zero, Time.deltaTime * lookAheadReturnSpeed);
}
Vector3 aheadTargetPos = target.position + lookAheadPos + Vector3.forward * offsetZ;
Vector3 newPos = Vector3.SmoothDamp(transform.position, aheadTargetPos, ref currentVelocity, damping);
transform.position = newPos;
lastTargetPosition = target.position;
}
}
Try
Vector3 aheadTargetPos = target.position + lookAheadPos + Vector3.forward * offsetZ;
Vector3 newPos = Vector3.SmoothDamp(transform.position, aheadTargetPos, ref currentVelocity, damping);
newPos.y = transform.position.y;
transform.position = newPos;
or
Vector3 aheadTargetPos = target.position + lookAheadPos + Vector3.forward * offsetZ;
aheadTargetPos.y = transform.position.y;
Vector3 newPos = Vector3.SmoothDamp(transform.position, aheadTargetPos, ref currentVelocity, damping);
transform.position = newPos;
You can set a minimum threshold value for the Y value of character. When characters jump you can save that transform point y and look for the distance between that point and character position.y If the character exceeds that threshold, than your camera can follow the character. Also, you can consider using Cinemachine. It is very powerful. (https://unity.com/unity/features/editor/art-and-design/cinemachine)

Categories

Resources