0
\$\begingroup\$
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;

public class SpaceshipCutscene : MonoBehaviour
{
    public Transform player;
    public Transform[] npcs;
    public Transform console;
    public Camera FPSCamera;
    public Camera mainCamera;
    public Animator[] anim;
    public float rotationSpeed = 3f;
    public float distanceFromConsole;


    private bool moveNpc = false;
    private float sp = 0f;
    private float distance;

    // Use this for initialization
    void Start()
    {

    }

    private void Update()
    {
        distance = Vector3.Distance(transform.position, npcs[0].transform.position);
        if (moveNpc)
        {
            // Soldier 2 rotating and looking at player
            Vector3 dir = player.position - npcs[0].position;
            dir.y = 0; // keep the direction strictly horizontal
            Quaternion rot = Quaternion.LookRotation(dir);
            // slerp to the desired rotation over time
            npcs[0].rotation = Quaternion.Slerp(npcs[0].rotation, rot, rotationSpeed * Time.deltaTime);

            var dist = Vector3.Distance(npcs[1].position, console.position);
            if (dist < distanceFromConsole)
            {
                sp += Time.deltaTime;
                sp = Mathf.Clamp(sp, 0f, 1f);
                anim[1].SetFloat("WalkingSpeed", sp);
            }

            Vector3 dirToComputer = console.transform.position - npcs[1].position;
            dirToComputer.y = 0;
            Quaternion rot1 = Quaternion.LookRotation(dirToComputer);
            npcs[1].rotation = Quaternion.Slerp(npcs[1].rotation, rot1, rotationSpeed * Time.deltaTime);

        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (HoriDoorManager.doorLockState == false && distance < 5f)
        {
            if (other.gameObject.tag == "SpaceshipCutscene")
            {
                FPSCamera.enabled = false;
                mainCamera.enabled = true;
                moveNpc = true;
                anim[0].SetBool("Aiming", true);
                anim[1].SetBool("Walktouse", true);
            }
        }
    }
}

When moving the player(transform) too fast it will not pass inside the line:

if (HoriDoorManager.doorLockState == false && distance < 5f)

But if I'm moving the player slow very slow or much slower then it will pass inside the line and make the rest of the code in the Update.

Before using the distance at all it was working fine but now I want to calculate the distance to make sure it will work only when the player is exit at specific direction.

But for some reason on high speed movement the distance calculation is not working good. It's not giving errors or exceptions it's just does nothing when exiting.

I did a test now and on the line:

if (HoriDoorManager.doorLockState == false && distance < 5f)

And changed it to:

if (HoriDoorManager.doorLockState == false)

And now it's working on any speed the character/player is moving. So the problem is when calculating the distance on high speed.

\$\endgroup\$
1
  • \$\begingroup\$ Does (transform.position - npcs[0].transform.position).magnitude work? \$\endgroup\$
    – Ryolu
    Commented Oct 23, 2018 at 5:42

1 Answer 1

1
\$\begingroup\$

Your distance computation is just fine but your logic is broken.

The distance is just a plain math, you put values in it and get the result but then you check if it's less than 5, and what if it's not? You end up with a situation where in one frame your object is way before some trigger, but in the next frame your object has moved so far that it passed the trigger and is still far away, but on the different side. This is a well known problem in physics with fast moving objects and it's called tunelling.

To solve this issue you can use lower speeds, shorter timestep for simulation or use special kind of collision algorithms known as sweep tests. In such tests you extrude your moving object along it's movement direction, so fast moving ball would become a cylinder from balls position in one frame to position in the next frame. Then you test collisions between cylinder and walls instead of ball-walls.

\$\endgroup\$
7
  • \$\begingroup\$ Now that I'm thinking about it I could add after the door the side I want to trigger another empty GameObject with a trigger let's say about 2.5f distance from the door trigger. And that empty GameObject with the trigger will start the cutscene. Then I can destroy the empty GameObject. Is that logic good idea ? \$\endgroup\$
    – Daniel Lip
    Commented Oct 23, 2018 at 12:50
  • 1
    \$\begingroup\$ It is some workaround but keep in mind that if you leave a small hole between triggers then your object may move to this hole one frame and then pass the second trigger another frame :) so this may still break. If you don't have playable area behind the doors then just create some big trigger, like 100m and you're done. \$\endgroup\$
    – kolenda
    Commented Oct 23, 2018 at 13:05
  • \$\begingroup\$ What I did in the end is added a new Cube on the side of the door I want to be the exit trigger. Changed the cube scale to be the size of the door trigger on the X and the cube is a bit inside the door trigger area so there is not space between them. Added a new script to the cube with a OnTriggerEnter and a flag set to true when entering. In the first script the door script on the OnTriggerExit I check for the tag and also set another flag to true. Then in the Update I'm checking if both exit here and enter there are true. \$\endgroup\$
    – Daniel Lip
    Commented Oct 23, 2018 at 14:25
  • 1
    \$\begingroup\$ This should work but it's hard to tell just by the description :). I'm not sure if Unity does sweep tests, if so then it should fix your problem completely. \$\endgroup\$
    – kolenda
    Commented Oct 23, 2018 at 14:35
  • 1
    \$\begingroup\$ I tried it few times now moved the player fast through the door and it's working. I can't think of other way to test it then just trying it over and over again. But for now it seems to be working :) \$\endgroup\$
    – Daniel Lip
    Commented Oct 23, 2018 at 14:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .