Daniel Lip
Daniel Lip

Reputation: 11319

How can I stop the character walking speed slowly to 0 before getting to touch the door?

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.

Upvotes: 1

Views: 190

Answers (1)

derHugo
derHugo

Reputation: 90629

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

Upvotes: 1

Related Questions