1
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Collision : MonoBehaviour
{
    public GameObject door;
    public Animator character;
    public DoorsLockManager doorslockmanager;

    private float speed;

    private void OnTriggerEnter(Collider other)
    {
        if(other.name == door.name &&
           doorslockmanager.locked == true)
        {
            character.SetFloat("Walking Speed", speed);
        }
    }

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        float distanceFromTarget = Vector3.Distance(character.transform.position, door.transform.position);

        if (distanceFromTarget < 3)
        {
            speed = (distanceFromTarget / 10) / 1;
        }
    }
}

In this case I'm checking for distance 3 from the door. The character does slowly reduce the walking speed. But it's never stop the character keep walking slowly through the door.

I want the character for example if it start slow down at distance 3 from door then stop walking speed 0 at distance 1 or 0.5f

Stop walking just a bit before the door. And not just suddenly to stop walking but to slowly reduce the speed to 0.

This is a working script. But I'm still confuse a bit about the speed calculation part:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Collision : MonoBehaviour
{
    public GameObject door;
    public Animator character;
    public DoorsLockManager doorslockmanager;

    private float speed = 0;
    private bool triggered = false;

    private void OnTriggerEnter(Collider other)
    {
        if (other.name == door.name &&
           doorslockmanager.locked == true)
        {
            triggered = true;
        }

        if(doorslockmanager.locked == false)
        {
            triggered = false;
        }
    }

    // Update is called once per frame
    void Update()
    {
        float distanceFromTarget = Vector3.Distance(character.transform.position, door.transform.position);

        if (triggered == true)
        {
            speed = (distanceFromTarget / 10);
            character.SetFloat("Walking Speed", speed);
            character.SetBool("Idle", true);
        }
    }
}

This line:

speed = (distanceFromTarget / 10);

It seems like the character is slowing down too fast at the first time instead slowly slow down smooth form walking.

Dubi Duboni
  • 813
  • 2
  • 17
  • 33
  • The thing you need is called friction. – Sebastian L Jan 27 '19 at 01:22
  • There are a few ways you can do this... You can use a Lerp with time.deltaTime, instead of a ratio of completion, you can do a distance check with a MoveTowards and a speed, if you are using a NavMesh there are some settings you can set to do this. – AresCaelum Jan 27 '19 at 03:21
  • @Eddge Could you show me example please ? My character is moving by animation the character have animator and using HumaondoidWalk animation to walk and move. So I don't want to use here MoveTowards since the character is already moving and walking when running the game using the HumanoidWalk. I want to make that if I set the distance to 3 like now slow down slowly to 0 but make sure it will get to speed 0 and stop before the door a bit before the door. – Dubi Duboni Jan 27 '19 at 08:14
  • @Eddge To change the speed I'm using the Animator parameter "Walking Speed". Maybe I should use other way/s to slow down but the character speed is set now by changing the "Walking Speed" parameter value. – Dubi Duboni Jan 27 '19 at 08:20
  • 2
    Btw what is that `/ 1` good for? – derHugo Jan 27 '19 at 10:09
  • I updated my question with a almost working script. In general it's working fine. But I'm still confused about the speed calculation part. The character change from walk to start slow down too fast at first time instead slowly smooth change from walk to slow down and to idle. The part form slow down to idle is fine but from walk to slow down is too fast. speed = (distanceFromTarget / 10); I'm lost with the speed calculation. – Dubi Duboni Jan 27 '19 at 22:35

1 Answers1

1

what you could try is mapping the distance between maxDistance(3) and minDistance(1) to a speed factor of 1 to 0 (see here):

public float minDistance;
public float maxDistance;
private float initialSpeed;

private void Update()
{
    float distanceFromTarget = Vector3.Distance(character.transform.position, door.transform.position);

    ClampSpeed(distanceFromTarget);
}


private void DampSpeed(float distance)
{
    // value between minDistance and maxDistance 
    // 1-3 in your case
    var clampedDistance = Mathf.Clamp(distance, minDistance, maxDistance);

    // This gives you a value between 0-1
    // where 1 means distance >= maxDistance
    // 0 means distance <= minDistance
    var mapped = (x - minDistance) / (maxDistance - minDistance);

    speed = initialSpeed * mapped;
    character.SetFloat("Walking Speed", speed);
}

You still have to get the initial speed somehow and be careful when to enable and disable this code block because one wouldn't be able to get away from the door once being to close to it ;)

Could look like

// Flag for enabling and disabling damping
private bool enableDamping;

// speed with which the player passed the 3m mark
private float initialSpeed;

private void Update()
{
    float distanceFromTarget = Vector3.Distance(character.transform.position, door.transform.position);

    if(distanceFromTarget > maxDistance)
    {
        // while far away only remember current speed and do nothing else
        initialSpeed = speed;
        enableDamping = true;
    }
    else if (distanceFromTarget <= maxDistance && distanceFromTarget > minDistance)
    {
        if(enableDamping)
        {
            DampSpeed(distanceFromTarget);
        }
    }
    else
    {
        if(enableDamping)
        {  
            // now speed should be zero but just to be sure
            speed = 0;
            character.SetFloat("Walking Speed", speed);
            // and the player minDistance from the door
            // you might want to disable the damping now so you can still move away again.
            enableDaming = false;
        }
    }
}

Note that it might still come to strange situations because if you enter the 3m range with a very low speed it might take a while until you finally reach the 1m and are able to move again...

But I hope it gives you an idea

derHugo
  • 83,094
  • 9
  • 75
  • 115