How can I add a slowdown effect when object is getting close to a target? - c#

using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.AI;
public class Waypoints : UnityEngine.MonoBehaviour
{
public List<Transform> waypoints = new List<Transform>();
public float movementSpeed = 5.0f;
public float slowdownSpeed = 1f;
public float rotationSpeed = 2.0f;
public float waypointDistance = 0.1f;
public float slowdownDistance = 7f;
public bool moveBackward = false;
public bool moveLoop = false;
public bool includeTransformPosition = false;
private Transform targetWaypoint;
private int targetWaypointIndex = 0;
private int lastWaypointIndex;
private bool includeTransform = true;
private GameObject go;
// Use this for initialization
void Start()
{
go = new GameObject();
go.transform.position = transform.position;
if (moveBackward && waypoints.Count > 2)
{
lastWaypointIndex = 0;
targetWaypoint = waypoints[waypoints.Count - 1];
}
else
{
lastWaypointIndex = waypoints.Count - 1;
targetWaypoint = waypoints[targetWaypointIndex]; //Set the first target waypoint at the start so the enemy starts moving towards a waypoint
}
}
// Update is called once per frame
void Update()
{
if (includeTransformPosition && includeTransform)
{
waypoints.Insert(0,go.transform);
includeTransform = false;
}
else
{
if (includeTransformPosition == false)
{
waypoints.Remove(go.transform);
includeTransform = true;
}
}
float movementStep = movementSpeed * Time.deltaTime;
float rotationStep = rotationSpeed * Time.deltaTime;
Vector3 directionToTarget = targetWaypoint.position - transform.position;
Quaternion rotationToTarget = Quaternion.LookRotation(directionToTarget);
transform.rotation = Quaternion.Slerp(transform.rotation, rotationToTarget, rotationStep);
float distance = Vector3.Distance(transform.position, targetWaypoint.position);
CheckDistanceToWaypoint(distance);
if(slowdownDistance < 7f)
{
movementSpeed -= movementSpeed * Time.deltaTime;
}
transform.position = Vector3.MoveTowards(transform.position, targetWaypoint.position, movementStep);
}
void CheckDistanceToWaypoint(float currentDistance)
{
if (currentDistance <= waypointDistance)
{
targetWaypointIndex++;
UpdateTargetWaypoint();
}
}
void UpdateTargetWaypoint()
{
if (targetWaypointIndex > lastWaypointIndex)
{
targetWaypointIndex = 0;
}
targetWaypoint = waypoints[targetWaypointIndex];
}
}
At this part I'm trying to slowdown the movement speed but it's not changing the speed at all :
if(slowdownDistance < 7f)
{
movementSpeed -= movementSpeed * Time.deltaTime;
}
What I'm trying to do when the transform start to move increase the speed slowly to some constant speed and then when the transform is getting closer to the waypoint then if the distance is less then 7 decrease the speed down to 0 so the object will stop at the waypoint then after X seconds move back the transform to the transform original position(go.transform) with the same increasing decreasing speed movement.
but I can't even make the first simple slowdown.

you set slowdownDistance to 7, i dont see you ever reducing it below 7 but you have if statement that executes only it it is under 7 do you reduce it elsewhere?
You probably planned to compare slowdownDistance to some distance rather than comparing it to its own value.

If you want to slow down the whole scene you could use a:
while(distance < range)
{
Time.timeScale = 1 - (distance / value);
}
with this you can change the value and so when the player come close time will be slown down mostly.
With the same idea you can do:
while(distance < range)
{
speed = speedInitial - (distance / value);
}
If you want to change just the speed of the player

Related

Horizontal movement of player causes egregious numbers when checking vertical velocity

Player movement is working (at least somewhat) now, however one issue remains, and that's the insane numbers the y velocity of the Rigidbody2D on the player. Since the isGrounded check I plan to add will use velocity for the sake of stability, this needs to be fixed.
It confuses me, considering the velocity is 0 normally, but whenever moving left or right it changes to said high numbers.
Movement code:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerM : MonoBehaviour
{
private PControls control;
Rigidbody2D rb;
SpriteRenderer sp;
Transform tr;
public float speed = 0f;
public float speedC;
public float heightSpeed = 5f;
public float heightC;
public bool grounded;
void Start()
{
control = new PControls();
control.Enable();
rb = GetComponent<Rigidbody2D>();
sp = GetComponent<SpriteRenderer>();
tr = GetComponent<Transform>();
}
// Update is called once per frame
void FixedUpdate()
{
RaycastHit2D hit = Physics2D.Raycast(rb.position, -Vector2.up);
Color color = new Color(0, 0, 1.0f);
Debug.DrawRay(transform.position, Vector2.down);
speedC = rb.velocity.magnitude;
var pos = control.Movement.Move.ReadValue<float>();
float GetVerticalSpeed() => rb.velocity.y;
if(pos == -1)
{
sp.flipX = true;
}
else if(pos == 1)
{
sp.flipX = false;
}
if((pos == 0) && (speed > 0.1f))
{
speed -= 3f * Time.deltaTime;
}
else if(speed < 1.4f)
{
speed += Mathf.Abs(pos) * 8 * Time.deltaTime;
}
if(speedC < 7f)
{
rb.AddForce(new Vector3((pos * 5), 0f) * speed * Time.deltaTime, ForceMode2D.Impulse);
}
var jump = control.Movement.Jump.ReadValue<float>();
Debug.Log(GetVerticalSpeed());
Vector3 v = rb.velocity;
v.y = 10;
if(jump == 1)
{
rb.velocity = v;
}
}
}
Seems the main issue was fixed by converting the height velocity to an integer using System.Math.Round():
float vel = rb.velocity.y;
heightC = (int)System.Math.Round(vel);
Not sure it's the best solution, but it's something..

Unity grappling more like Tarzan

I am trying to make a grappling hook more fluent but as of right now it is very choppy and does not have the right feel. It currently makes a line and pulls the player there. I have not tried anything yet because I am not even sure we're to start on fixing this. Here is all the grappling code below. `using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(SFPSC_PlayerMovement))] // PlayerMovement also requires Rigidbody
public class SFPSC_GrapplingHook : MonoBehaviour
{
public bool IsGrappling
{
get { return isGrappling; }
}
private SFPSC_PlayerMovement pm;
private Rigidbody rb;
private int segments;
private void Start()
{
segments = rope.segments;
pm = this.GetComponent<SFPSC_PlayerMovement>();
rb = this.GetComponent<Rigidbody>();
}
private bool isGrappling = false;
private void Update()
{
if (crossHairSpinningPart != null)
{
// we need 2 raycasts bc w/ 1 you can grapple through colliders which isn't good
if (Physics.Raycast(SFPSC_FPSCamera.cam.transform.position, SFPSC_FPSCamera.cam.transform.forward, out hitInfo, maxGrappleDistance, layerMask))
{
hitName = hitInfo.collider.name;
if (Physics.Raycast(SFPSC_FPSCamera.cam.transform.position, SFPSC_FPSCamera.cam.transform.forward, out hitInfo, maxGrappleDistance))
{
if (hitName != hitInfo.collider.name)
goto _else;
crossHairSpinningPart.gameObject.SetActive(true);
crossHairSpinningPart.Rotate(Vector3.forward * crossHairSpinSpeed * Time.deltaTime);
goto _out;
}
}
_else:
crossHairSpinningPart.gameObject.SetActive(false);
}
_out:
if (!isGrappling)
{
if (Input.GetKeyDown(SFPSC_KeyManager.Grapple))
Grapple();
return;
}
else
{
if (!Input.GetKey(SFPSC_KeyManager.Grapple))
UnGrapple();
GrappleUpdate();
return;
}
}
[Header("Properties")]
public float maxGrappleDistance = 100.0f;
public SFPSC_Rope rope;
public float maximumSpeed = 100.0f;
public float deceleration = 2500.0f; // This is how much the player is going to decelerate after stopped grappling
public float deceleratingTime = 1.4f; // This is the time the decelerating is going to act on the player after stopped grappling
public RectTransform crossHairSpinningPart;
public float crossHairSpinSpeed = 200.0f;
public float distanceToStop = 2.0f;
public LayerMask layerMask;
public float grappleCooldown = 1.0f;
private bool isBlocked = false;
private Transform location; // the grappled location
private RaycastHit hitInfo;
private string hitName;
public void Grapple()
{
if (isBlocked)
return;
// we need 2 raycasts bc w/ 1 you can grapple through colliders which isn't good
if (Physics.Raycast(SFPSC_FPSCamera.cam.transform.position, SFPSC_FPSCamera.cam.transform.forward, out hitInfo, maxGrappleDistance, layerMask))
{
hitName = hitInfo.collider.name;
if (Physics.Raycast(SFPSC_FPSCamera.cam.transform.position, SFPSC_FPSCamera.cam.transform.forward, out hitInfo, maxGrappleDistance))
{
if (hitName != hitInfo.collider.name)
return;
// We create a GameObject and we parent it to the grappled object.
// If we don't parent it to the object and the object moves the player is stuck only on one location instead of the moving object.
location = new GameObject().transform;//Instantiate(new GameObject(), hitInfo.point, Quaternion.identity).transform;
location.position = hitInfo.point;
location.parent = hitInfo.collider.transform;
if (decelerateTimer != 0.0f)
StopCoroutine(Decelerate());
pm.DisableMovement();
// Rope attaching
rope.segments = (int)((hitInfo.distance / maxGrappleDistance) * segments);
rope.Grapple(transform.position, hitInfo.point);
rb.useGravity = false;
isGrappling = true;
}
}
}
private Vector3 grappleForce;
public void UnGrapple()
{
if (!isGrappling)
return;
if (location != null)
Destroy(location.gameObject);
if (decelerateTimer == 0.0f)
StartCoroutine(Decelerate());
else
decelerateTimer = 0.0f;
pm.EnableMovement();
// Rope detaching
rope.UnGrapple();
Invoke("UnblockGrapple", grappleCooldown);
rb.useGravity = true;
isGrappling = false;
}
private void UnblockGrapple()
{
isBlocked = false;
}
private float decelerateTimer = 0.0f, max;
private IEnumerator Decelerate()
{
WaitForEndOfFrame wfeof = new WaitForEndOfFrame();
max = deceleratingTime * Mathf.Clamp01(targetDistance / 10.0f) * Mathf.Clamp01(rb.velocity.magnitude / 30.0f);
for (; decelerateTimer < max; decelerateTimer += Time.deltaTime)
{
rb.AddForce(-rb.velocity.normalized * deceleration * (1.0f - decelerateTimer / max) * Mathf.Clamp01(rb.velocity.sqrMagnitude / 400.0f) * Time.deltaTime, ForceMode.Acceleration);
yield return wfeof;
}
decelerateTimer = 0.0f;
}
private Vector3 dir;
private float speed = 0.0f, targetDistance;
private void GrappleUpdate()
{
if (location == null)
return;
targetDistance = Vector3.Distance(transform.position, location.position);
rope.segments = (int)((targetDistance / maxGrappleDistance) * segments);
dir = (location.position - transform.position).normalized;
rb.velocity = Vector3.Lerp(rb.velocity, dir * maximumSpeed * Mathf.Clamp01(targetDistance / (4.0f * distanceToStop)), Time.deltaTime);
// Rope updating
rope.UpdateStart(transform.position);
rope.UpdateGrapple();
}
private Vector3 ClampMag(Vector3 vec, float maxMag)
{
if (vec.sqrMagnitude > maxMag * maxMag)
vec = vec.normalized * maxMag;
return vec;
}
}
`
Try using FixedUpdate instead of Update for physics based work (basically all of your code in Update right now). Update is dependent on your computer's clock speed and refresh rate (more or less), and gets called at fairly irregular intervals, because the next update is called in the next frame, after the present frame has finished processing. FixedUpdate makes it frame-rate independent.
Also, you can cap your framerate using Application.targetFrameRate and cap it to a decent FPS.
You could also multiply your movement with Time.deltaTime for smoother movement, although this is a standard practice and yet debatable for use as a smoothing value.

How can I lerp a vector3 by time not by position?

using UnityEngine;
using UnityEditor;
using System.Collections;
public class LerpExample : MonoBehaviour
{
[Header("Animation-Curve")]
public AnimationCurve slideCurve;
public Transform finalPosition;
private Vector3 initialPosition;
public float time;
private void Awake()
{
initialPosition = transform.position;
}
private void Start()
{
StartCoroutine(MoveObject());
}
private void Update()
{
}
private IEnumerator MoveObject()
{
float i = 0;
float rate = 1 / time;
while (i < 1)
{
i += rate * Time.deltaTime;
transform.position = Vector3.Lerp(initialPosition, finalPosition.position, slideCurve.Evaluate(i));
yield return 0;
}
}
}
I'm using animation curves to make the transform start decreasing speed and then when getting close to the target to decrease the speed.
but I ant now to lerp without finalPosition position but with finalPosition as time.
for example, if I will set the time to 7 so the transform will start lerp from its position, and after 7 seconds where ever the transform is reached decrease down the speed back.
The target instead position will be time.
Now it start to slow down near the target after 7 seconds or in 7 seconds for example 7 seconds but I want that it will start to slow down in 7 seconds without a vector3 target just after 7 seconds slow down and stop.
I have this situation :
An object that starts moving by force with a rigidbody on the terrain.
While the object is moving I want the player to start moving too beside the object with the rigidbody.
The player should start moving slowly to max speed than when the other moving object near stops moving the player should slowly slow down to stop.
IN general, I used the SpeedUp and SlowDown methods but they were working fine when I wanted to do it when moving the player forward. The problem is that the parameter "Forward" will move the player only in the forward direction.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
using FIMSpace.FLook;
public class Rolling : MonoBehaviour
{
public GameObject mainCam;
public CinemachineFreeLook freeLookCamGameplay;
public CinemachineFreeLook freeLookCamPickUp;
public Transform player;
public Transform crate;
public Transform cube;
public Animation anim;
public UnlockCrate unlockCrate;
public float timeToStopRolling;
public float speed;
public float waitBeforeSlowdown;
public float startDrag;
public float endDrag = 50;
public float rotationSpeed;
public static bool hasStopped = false;
private bool crateOpenOnce = false;
private bool alreadyRolling;
private Rigidbody rb;
private Quaternion defaultRotation;
private Animator animator;
private bool startSpeedUp = true;
public float lerpTimeMultiplicator = 0.25f;
private float timeElapsed = 0;
private float lerpDuration = 3f;
private float startValue = 1;
private float endValue = 0;
private float valueToLerp = 0;
private bool triggerOnce = false;
private void Start()
{
rb = GetComponent<Rigidbody>();
defaultRotation = rb.rotation;
animator = player.GetComponent<Animator>();
}
private void Update()
{
var distance = Vector3.Distance(crate.position, player.position);
if (distance < 1.7f && crateOpenOnce == false && unlockCrate.HasOpened())
{
rb.isKinematic = false;
crateOpenOnce = true;
}
if(crateOpenOnce && startSpeedUp)
{
StartCoroutine(SpeedUp());
StartCoroutine(WaitBeforeSlowdown());
startSpeedUp = false;
}
if(animator.GetFloat("Forward") == 0f && startSpeedUp == false &&
triggerOnce == false)
{
triggerOnce = true;
}
}
private IEnumerator Slowdown()
{
while(timeElapsed < lerpDuration)
{
timeElapsed += Time.deltaTime;
valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / lerpDuration);
animator.SetFloat("Forward", valueToLerp);
// Yield here
yield return null;
}
}
private IEnumerator SpeedUp()
{
while(timeElapsed < lerpDuration)
{
timeElapsed += Time.deltaTime;
valueToLerp = Mathf.Lerp(endValue, startValue, timeElapsed / lerpDuration);
animator.SetFloat("Forward", valueToLerp);
// Yield here
yield return null;
}
}
private IEnumerator WaitBeforeSlowdown()
{
yield return new WaitForSeconds(13f);
timeElapsed = 0;
StartCoroutine(Slowdown());
}
private void OnCollisionEnter(Collision collision)
{
//NOTE: In general you should go for Tags instead of the name
if (collision.gameObject.name == "Crate_0_0")
{
if (crateOpenOnce)
{
rb.drag = 0f;
// Directly start a routine here (if none is already running)
if (!alreadyRolling) StartCoroutine(RollingRoutine());
}
}
}
private void OnCollisionExit(Collision collision)
{
if (collision.gameObject.name == "Crate_0_0")
{
var brain = mainCam.GetComponent<CinemachineBrain>();
brain.m_DefaultBlend.m_Time = 1f;
freeLookCamGameplay.enabled = false;
freeLookCamPickUp.enabled = true;
}
}
private Vector3 GetRandomDirection()
{
var rnd = Random.insideUnitSphere;
rnd.y = 0;
return rnd.normalized;
}
private IEnumerator RollingRoutine()
{
// Just in case prevent concurrent routines
if (alreadyRolling) yield break;
// Block new routines from starting
alreadyRolling = true;
// Get the random direction for this routine
var rollDirection = GetRandomDirection();
// Roll for the given time within the FixedUpdate call
for (var timePassed = 0f; timePassed < timeToStopRolling; timePassed += Time.deltaTime)
{
// Wait until you are in FixedUpdate
// the code after this is now executed within FixedUpdate
yield return new WaitForFixedUpdate();
rb.AddForce(Vector3.right /*rollDirection*/ * speed * Time.deltaTime);
}
// Wait before slowing down
yield return new WaitForSeconds(waitBeforeSlowdown);
// Do slow down and rotate to default until both conditions are fulfilled
var dragLerpFactor = 0f;
// Store the original drag to reset it later
var defaultDrag = rb.drag;
while (!Mathf.Approximately(rb.velocity.sqrMagnitude, 0) || rb.rotation != defaultRotation)
{
// Again wait until you are in FixedUpdate
yield return new WaitForFixedUpdate();
dragLerpFactor += Time.deltaTime * lerpTimeMultiplicator;
rb.drag = Mathf.Lerp(startDrag, endDrag, dragLerpFactor);
rb.MoveRotation(Quaternion.RotateTowards(rb.rotation, defaultRotation, rotationSpeed * Time.deltaTime));
}
// Just to be sure to end with clean value assign once
rb.rotation = defaultRotation;
rb.drag = defaultDrag;
rb.velocity = Vector3.zero;
hasStopped = true;
Destroy(transform.GetComponent<Rigidbody>());
Destroy(transform.GetComponent<SphereCollider>());
}
}
That is why I'm trying to use the code in the LerpExample script.
The main goal is to move the player slowly to max speed and then slowly to stop beside the rolling t transform in the Rolling script.

How can I calculate a moving object speed?

The goal is to show both transform and speed movement speed in text1 and text2.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Follow : MonoBehaviour
{
public Transform targetToFollow;
public Text text;
public Text text1;
public Text text2;
public float lookAtRotationSpeed;
public float moveSpeed;
private float minMoveSpeed = 0f;
private Vector3 originPos;
// Start is called before the first frame update
void Start()
{
originPos = targetToFollow.position;
}
// Update is called once per frame
void Update()
{
Vector3 lTargetDir = targetToFollow.position - transform.position;
lTargetDir.y = 0.0f;
transform.rotation = Quaternion.RotateTowards(transform.rotation,
Quaternion.LookRotation(lTargetDir), Time.time * lookAtRotationSpeed);
var distance = Vector3.Distance(transform.position, targetToFollow.position);
text.text = "Transform Distance From Target " + distance.ToString();
float ms = moveSpeed;
if (distance > 5f)
{
ms = moveSpeed + 0.5f; //move faster
}
else if (distance < 1.5f)
{
ms = Mathf.Max(minMoveSpeed, ms - 0.3f); // move slower
}
else
{
default value that equal moveSpeed here
transform.position = Vector3.MoveTowards(transform.position, targetToFollow.position, Time.deltaTime * ms);
}
if(distance < 0.5f && originPos == targetToFollow.position)
{
ms = 0f;
}
transform.position = Vector3.MoveTowards(transform.position, targetToFollow.position, Time.deltaTime * ms);
originPos = targetToFollow.position;
}
}
Now I'm setting to text the transform distance from the target.
But I want to add now to text1 and text2 the speed movement of the transform and the target.
In the end there will be 3 texts ui's that will show the distance and movement speeds.
I tried like this for the target speed :
var speedPerSec = Vector3.Distance(originPos, targetToFollow.position) / Time.deltaTime;
text1.text = "Target Speed Per Second " + speedPerSec.ToString();
but when the target is moving the text of the speed the speedPerSec.toString() is blinking fast and not smooth like the distance in the first text.
maybe it's blinking because it's showing the speed a lot after the zero point like : 0.00656555 ?
Since you want to track the speed of multiple objects (your transform and the target) the easiest way is to introduce a separate object handling the tracking and use an array of these.
[Serializable]
private class SpeedTracking
{
public Transform trackedObject;
public Text uiOutput;
private Vector3 _position;
private float _speed;
public void Update(float elapsedTime, float changeThreshold)
{
Vector3 newPos = trackedObject.position;
float newSpeed = Vector3.Distance(newPos, _position) / elapsedTime;
if ((newSpeed == 0 && _speed != 0) || Mathf.Abs(newSpeed - _speed) > changeThreshold)
{
_speed = newSpeed;
uiOutput.text = $"speed: {newSpeed:F3}";
}
_position = newPos;
}
}
private const float SPEED_CHANGE_THRESHOLD = 0.001F;
[SerializeField]
private SpeedTracking[] _trackings;
void OnEnable()
{
if (_trackings.Any(t => t.trackedObject == null || t.uiOutput == null))
{
Debug.LogError("at least one invalid tracking found");
enabled = false;
}
}
void Update()
{
//[...]
UpdateTrackings();
}
void UpdateTrackings()
{
foreach (SpeedTracking tracking in _trackings)
{
tracking.Update(Time.deltaTime, SPEED_CHANGE_THRESHOLD);
}
}
I also added a format to your output string (F3) showing only 3 decimal digits. (This alone would solve the flickering, but why update the ui more often than necessary?)
If you only want to know how much velocity of object in specific time
you can do something like this.
public class VelocityDisplayer : MonoBehaviour
{
public Transform Object; // your target gameobject
public Text View; // your text object
private Vector3 _position; // last position of target
private void OnEnable() {
_position = Object.transform.position;
}
private void Update() {
var dt = Time.deltaTime;
var current = Object.transform.position;
var delta = Vector3.Distance(current, _position);
var velocity = delta / dt;
View.text = (velocity).ToString("#,##0.000");
// replace current position
_position = current;
}
}
but this show actual speed which depend on game world/physics of object not your setup movement speed variable
PS1. I prefer to use update because is UI scope
PS2. I prefer to split new class to track object

Getting the distance of wall(Multiple objects with same tag)

I'm trying to get the distance between my player, and the nearest object with the tag 'wall' however I can't seem to get it to work.
To my knowledge my code isn't working at all.
So my question is;
What am I doing wrong? Again, I want to find the distance from my player and the nearest object with the tag 'wall'. If I'm near a object with the tag 'wall' I want it to set the variable to true.(nearWall = true) then once I'm away from the object(About 10.0f) I want it back to false.(nearWall = false)
This is the code I have been working with.
using UnityEngine;
using System.Collections;
public class PlayerMotor : MonoBehaviour {
private CharacterController controller;
private Vector3 moveVector;
private float speed = 2.0f;
private float verticalVelocity = 0.0f;
private float gravity = 12.0f;
private bool nearWall;
public GameObject playerObject;
GameObject closestObject;
float distance = Mathf.Infinity;
public float distanceToWall = Mathf.Infinity;
private void Start() {
nearWall = false;
playerObject = GameObject.Find("Player");
distanceToWall = 0;
controller = GetComponent<CharacterController> ();
}
public void getNearestWall()
{
if (distance <= 10.0f) {
nearWall = true;
print ("Near wall!");
}
else
nearWall = false;
}
GameObject findNearestWall()
{
GameObject[]objectArray;
objectArray = GameObject.FindGameObjectsWithTag("wall");
Vector3 position = playerObject.transform.position;
foreach(GameObject currentObject in objectArray)
{
Vector3 distanceCheck = currentObject.transform.position - position;
float currentDistance = distanceCheck.sqrMagnitude;
if (currentDistance < distance)
{
closestObject = currentObject;
distance = currentDistance;
}
}
return closestObject;
}
private void Update()
{
findNearestWall ();
moveVector = Vector3.zero;
if (controller.isGrounded)
{
verticalVelocity = -0.5f;
}
else
{
verticalVelocity -= gravity * Time.deltaTime;
}
if (Input.GetMouseButton (0)) {
if (!nearWall) {
if (Input.mousePosition.x > Screen.width / 2)
moveVector.x = speed;
else
moveVector.x = -speed;
}
else
{
moveVector.x = transform.forward.x * speed;
transform.Rotate(new Vector3(0, -90, 0));
}
}
moveVector.y = verticalVelocity;
moveVector.z = transform.forward.z * speed;
controller.Move (moveVector * Time.deltaTime);
}
}
One thing is that you are not calling getNearestWall() method - which is actually changing the flag - anywhere.
And second why don't you just try:
currentDistance = Vector3.Distance(currentObject.transform.position, position);
When calculating distance
first of all you need to call getNearestWall(); inside the Update() method ( after findNearestWall() of course ). also what you are doing now is getting the minimal distance the player reached in the whole game. you might want to add distance = Mathf.Infinity; in top of findNearestWall() so it will something like this:
GameObject findNearestWall()
{
GameObject[] objectArray;
objectArray = GameObject.FindGameObjectsWithTag("wall");
distance = Mathf.Infinity;
Vector3 position = playerObject.transform.position;
foreach (GameObject currentObject in objectArray)
{
Vector3 distanceCheck = currentObject.transform.position - position;
float currentDistance = distanceCheck.sqrMagnitude;
if (currentDistance < distance)
{
closestObject = currentObject;
distance = currentDistance;
}
}
return closestObject;
}
now whenever you get near a wall it should print Near wall!
note:
also you are calling FindObjectsWithTag() at an Update method which might significantly drain your processing power. you might want to avoid that by declaring a private GameObject[] objectArray in the class.
and then use objectArray = GameObject.FindGameObjectsWithTag("wall"); once at Awake() or Start()

Categories

Resources