0
\$\begingroup\$

I'm using the droid (Called it NAVI) to be like helper in the game. By default the droid is position a bit far from the player and act like a mouse cursor. When I move the player around the droid is moving with him. When the droid is getting over interactable objects he start rotating.

Then when the droid is on interactable object I can click and get information about the object. When i move to none interactable objects the droid stop rotating. When i press on F key the droid is rotating smooth getting closer to the player and back like a mouse cursor.

The problem is when I'm trying to move in or out doors for example since the droid position is a bit far from the player the droid is stuck in the door. The droid is outside the door but the player is not so the door keep closing and open over again.

What I'm trying to do is some how to make the droid to act like a mouse cursor but I'm not sure how to use it with doors for example.

I recorded a small short video clip showing the problem. First problem is when the droid small far from the player like a cursor it's not detecting the door and the door will not open.

Only if I press F and the droid is now bigger and close to me when I'm moving to the door the door will open.

Second problem is when the door is open and I'm moving forward the droid is outside but the player is not yet outside so the door get confusing and start closing.

Video clip

This is a screenshot of the player and it's inspector on the right. And the script Detect Interactable attached to it:

Player

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

public class DetectInteractable : MonoBehaviour
{
    public Camera cam;
    public float distanceToSee;
    public string objectHit;
    public bool interactableObject = false;
    public Transform parentToSearch;
    public static bool detected = false;

    private RaycastHit whatObjectHit;
    private bool clickForDescription = false;
    private int layerMask = 1 << 8;

    private void Start()
    {

    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            clickForDescription = true;
        }

        Debug.DrawRay(cam.transform.position, cam.transform.forward * distanceToSee, Color.magenta);
        if (Physics.Raycast(cam.transform.position, cam.transform.forward, out whatObjectHit, distanceToSee, layerMask))
        {
            detected = true;
            objectHit = whatObjectHit.collider.gameObject.name;
            interactableObject = true;
            print("Hit ! " + whatObjectHit.collider.gameObject.name);
        }
        else
        {
            detected = false;
            clickForDescription = false;
            print("Not Hit !");
        }
    }

    private void OnGUI()
    {
        if (clickForDescription == true)
        {
            ProcessOnGUI(parentToSearch);
        }
    }

    void ProcessOnGUI(Transform parent, int level = 0)
    {
        foreach (Transform child in parent)
        {
            if (child.GetComponent<ItemInformation>() != null)
            {
                ItemInformation iteminformation = child.GetComponent<ItemInformation>();
                if (child.name == objectHit)
                {
                    var centeredStyle = GUI.skin.GetStyle("Label");
                    centeredStyle.alignment = TextAnchor.UpperCenter;
                    GUI.Box(new Rect(
                          Screen.width / 2 - 50 + 20 * level, // <== INDENTATION
                          Screen.height / 2 - 25, 100, 50),
                        iteminformation.description, centeredStyle);
                }
            }

            // Process next deeper level
            ProcessOnGUI(child, level + 1);
        }
    }

    public class ViewableObject : MonoBehaviour
    {
        public string displayText;
        public bool isInteractable;
    }
}

Screenshot of the Main Camera and it's inspector:

Main Camera

Screenshot of the NAVI (The droid) and it's inspector:

Navi

And last screenshot of the Objects Manipulation gameobject and it's inspector:

Objects Manipulation

And the Objects Manipulation script:

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

public class ObjectsManipulation : MonoBehaviour
{
    //Scaling
    private Scaling scaling;

    //Lights
    public DimLights dimlights;
    private Coroutine lightCoroutine;

    //Colors
    private Colors colors;

    //Rotating
    private Rotating rotating;

    private void Start()
    {
        scaling = GetComponent<Scaling>();
        scaling.Inits();

        colors = GetComponent<Colors>();
        colors.Start();

        rotating = GetComponent<Rotating>();
    }

    // Use this for initialization
    void Update()
    {
        //Scaling
        if (Input.GetKeyDown(KeyCode.F))
        {
            //Flip the scale direction when F key is pressed
            scaling.scaleUp = !scaling.scaleUp;

            //Stop old coroutine
            if (scaling.scaleCoroutine != null)
                StopCoroutine(scaling.scaleCoroutine);

            if (lightCoroutine != null)
                StopCoroutine(lightCoroutine);


            //Scale  up
            if (scaling.scaleUp)
            {
                //Start new coroutine and scale up within 5 seconds and return the coroutine reference
                rotating.rotateBack = false;
                scaling.scaleCoroutine = StartCoroutine(scaling.scaleOverTime(scaling.objectToScale, scaling.maxSize, scaling.duration));
                lightCoroutine = StartCoroutine(dimlights.dimLightOverTime(1, scaling.duration));
            }

            //Scale Down
            else
            {
                //Start new coroutine and scale up within 5 seconds and return the coroutine reference
                rotating.rotateBack = true;
                scaling.scaleCoroutine = StartCoroutine(scaling.scaleOverTime(scaling.objectToScale, scaling.minSize, scaling.duration));
                lightCoroutine = StartCoroutine(dimlights.dimLightOverTime(0, scaling.duration)); ;
            }
        }
        //Rotate
        if (Input.GetKey(KeyCode.R) && !scaling.scaleUp)
        {
            rotating.x += Time.deltaTime * rotating.rotationSpeed;
            scaling.objectToScale.transform.localRotation = Quaternion.Euler(0, 0, rotating.x);
            rotating.keyPressed = true;
        }
        if (Input.GetKeyUp(KeyCode.R))
        {
            rotating.keyPressed = false;
        }

        if (!rotating.keyPressed && !scaling.scaleUp && rotating.rotateBack == false
            && DetectInteractable.detected == false)
        {
            scaling.objectToScale.transform.rotation = Quaternion.LookRotation(Camera.main.transform.forward);
        }

        if (DetectInteractable.detected == true && !scaling.scaleUp)
        {
            rotating.x += Time.deltaTime * rotating.rotationSpeed;
            scaling.objectToScale.transform.localRotation = Quaternion.Euler(0, 0, rotating.x);
        }
    }
}

The rotating script:

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

public class Rotating : MonoBehaviour
{
    public float rotationSpeed;
    public float rotationDuration;
    public float x;
    public bool keyPressed = false;
    public bool rotateBack = false;
}

The scaling script:

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

public class Scaling : MonoBehaviour
{
    public GameObject objectToScale;
    public GameObject lookAtTarget;
    public float duration = 1f;
    public Vector3 minSize;
    public Vector3 maxSize;
    public bool scaleUp = false;
    public Coroutine scaleCoroutine;

    public void Inits()
    {
     objectToScale.transform.localScale = minSize;
    }

    public IEnumerator scaleOverTime(GameObject targetObj, Vector3 toScale, float duration)
    {
        float counter = 0;
        Vector3 startScaleSize = targetObj.transform.localScale;

        while (counter < duration)
        {
            counter += Time.deltaTime;
            targetObj.transform.localScale = Vector3.Lerp(startScaleSize, toScale, counter / duration);
            if (scaleUp)
            {
                var lookPos = lookAtTarget.transform.position - objectToScale.transform.position;
                lookPos.y = 0;
                var rotation = Quaternion.LookRotation(lookPos);
                objectToScale.transform.rotation = Quaternion.Slerp(objectToScale.transform.rotation, rotation, counter / duration);
            }
            else
            {
                var lookPos = lookAtTarget.transform.position - objectToScale.transform.position;
                lookPos.y = 0;
                var rotation = Quaternion.LookRotation(Camera.main.transform.forward);
                objectToScale.transform.rotation = Quaternion.Slerp(objectToScale.transform.rotation, rotation, counter / duration);
            }

            yield return null;
        }
    }
}

The main problem is when moving for example between doors since the NAVI droid is not like the mouse cursor but it's object that positioned close/far from the player the doors get confuse. I can't pass smooth through the doors.

This is a screenshot of one of the doors and it's inspector:

Door

And the script attached to the door:

using UnityEngine;
using System.Collections;

public class DoorVert : MonoBehaviour {

    public float translateValue;
    public float easeTime;
    public OTween.EaseType ease;
    public float waitTime;
    public Light[] lt;
    public Renderer[] renderers;
    public bool doorLocked = false;
    public bool locked = false;

    private Vector3 StartlocalPos;
    private Vector3 endlocalPos;


    private void Start(){
        StartlocalPos = transform.localPosition;    
        gameObject.isStatic = false;

        if (doorLocked == true)
        {
            for (int i = 0; i < lt.Length; i++)
            {
                lt[i].color = Color.red;
                renderers[i].material.color = Color.red;
            }
        }
    }

    public void OpenDoor(){
        if (doorLocked == false)
        {
            OTween.ValueTo(gameObject, ease, 0.0f, -translateValue, easeTime, 0.0f, "StartOpen", "UpdateOpenDoor", "EndOpen");
            GetComponent<AudioSource>().Play();
        }
    }

    private void UpdateOpenDoor(float f){
        if (doorLocked == false)
        {
            Vector3 pos = transform.TransformDirection(new Vector3(0, 1, 0));
            transform.localPosition = StartlocalPos + pos * f;
        }

    }

    private void UpdateCloseDoor(float f){
        if (doorLocked == false)
        {
            Vector3 pos = transform.TransformDirection(new Vector3(0, -f, 0));
            transform.localPosition = endlocalPos - pos;
        }

    }

    private void EndOpen(){
        if (doorLocked == false)
        {
            endlocalPos = transform.localPosition;
            StartCoroutine(WaitToClose());
        }
    }

    private IEnumerator WaitToClose(){

        yield return new WaitForSeconds(waitTime);
        OTween.ValueTo( gameObject,ease,0.0f,translateValue,easeTime,0.0f,"StartClose","UpdateCloseDoor","EndClose");
        GetComponent<AudioSource>().Play();
    }

    private void Update()
    {
        if (locked == true)
        {
            doorLocked = true;
            for (int i = 0; i < lt.Length; i++)
            {
                lt[i].color = Color.red;
                renderers[i].material.color = Color.red;
            }
        }
        else
        {
            doorLocked = false;
            for (int i = 0; i < lt.Length; i++)
            {
                lt[i].color = Color.green;
                renderers[i].material.color = Color.green;
            }
        }
    }
}

This script is calling OpenDoor():

using UnityEngine;
using System.Collections;

public class VertDoorManager : MonoBehaviour {

    public DoorVert door1;

    void OnTriggerEnter(){
        if (door1!=null){
            door1.OpenDoor();   
        }

    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ youll need to post your inspector and script for doors \$\endgroup\$ – Stephan Jan 15 '18 at 19:04
  • \$\begingroup\$ @Stephan I just updated my question with the door inspector screenshot and the script that attached to the door. \$\endgroup\$ – jdoedoe doedoe Jan 15 '18 at 20:10
  • \$\begingroup\$ what's calling OpenDoor()? \$\endgroup\$ – Stephan Jan 15 '18 at 20:14
  • \$\begingroup\$ @Stephan Updated the question again with the script that is calling OpenDoor() the script name is VertDoorManager \$\endgroup\$ – jdoedoe doedoe Jan 15 '18 at 21:03
  • 1
    \$\begingroup\$ I think the answer below is on the right track. My initial impression is that the two colliders, the player and the drone, are overlapping the trigger enough to cause the cycling. You may want to look into ontriggerstay to maybe interrupt the close animation \$\endgroup\$ – Stephan Jan 15 '18 at 21:19
2
\$\begingroup\$

This does not directly answer the mouse cursor question, but may provide an alternative.

You could check both the player and NAVI for the trigger to open the door, then she could open if it closed behind the player.

Or, in the case some doors may lock:

Each time the player exits the door's collider teleport NAVI to a location next to the player.

\$\endgroup\$
  • \$\begingroup\$ It was simple then i thought. I just unchecked on the NAVI(Droid) the Box Collider component so it will not use it. Now only the Player have the Capsule Collider so now the door/s open and close when the player is moving through and this solved the problem. Thanks. \$\endgroup\$ – jdoedoe doedoe Jan 15 '18 at 21:42
  • \$\begingroup\$ @jdoedoedoedoe if you solved the problem by a different method, you should add an answer describing that method, and accept that. There's nothing wrong with answering your own questions here. \$\endgroup\$ – DMGregory Jan 15 '18 at 21:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.