eye-therapy-2 / Assets / Scripts / Eye Simulation / EyeSimulation.cs
EyeSimulation.cs
Raw
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;

public class EyeSimulation : MonoBehaviour
{
    [Header("Oscillation")]
    public bool oscillationActive = true;
    public float oscillationTime = 0.1f;
    [Vector3Range(0, 0.12f, 0, 0.12f, 0, 0.12f, true)]
    public Vector3 leftEyeMaxOffset = new Vector3(0.01f, 0.01f, 0.01f);
    [Vector3Range(0, 0.12f, 0, 0.12f, 0, 0.12f, true)]
    public Vector3 rightEyeMaxOffset = new Vector3(0.01f, 0.01f, 0.01f);

    [Header("Deviation")]
    [Range(-60, 60)]
    public float angleLH = 0;
    [Range(-60, 60)]
    public float angleRH = 0;
    [Range(-60, 60)]
    public float angleLV = 0;
    [Range(-60, 60)]
    public float angleRV = 0;

    [Header("Prefabs")]
    public GameObject eye;
    [Min(0f)] public float eyeScale = 1f;
    [Range(0, 0.2f)] public float eyeDistanceFromCenter = 0.1f;

    [Header("Target")]
    public Transform target;
    private Vector3 leftEyeTarget;
    private Vector3 rightEyeTarget;

    public bool renderViewLines = true;
    public LineRenderer RightLaser;
    public LineRenderer LeftLaser;
    public LineRenderer RightDeviation;
    public LineRenderer LeftDeviation;
    [Min(1)] public float viewDistance = 100f;

    // Eyes variables
    private GameObject leftEye;
    private GameObject rightEye;
    private Vector3 leftEyeDir = Vector3.zero;
    private Vector3 rightEyeDir = Vector3.zero;
    private Vector3 leftEyeOffset = Vector3.zero;
    private Vector3 rightEyeOffset = Vector3.zero;

    public Vector4 EyeData
    {
        get
        {
            float lx = angleLH + leftEyeOffset.x;
            float ly = angleLV + leftEyeOffset.y;
            float rx = angleRH + rightEyeOffset.x;
            float ry = angleRV + rightEyeOffset.y;
            return new Vector4(lx, ly, rx, ry);
        }
    }
    
    private void Start()
    {
        leftEye = Instantiate(eye, transform.position, Quaternion.identity, transform);
        leftEye.name = "Left Eye";
        leftEye.transform.localScale = new Vector3(eyeScale, eyeScale, eyeScale);
        rightEye = Instantiate(eye, transform.position, Quaternion.identity, transform);
        rightEye.name = "Right Eye";
        rightEye.transform.localScale = new Vector3(eyeScale, eyeScale, eyeScale);
        LoadEyePos();
        leftEyeTarget = rightEyeTarget = target.position;
        StartCoroutine(Oscillation());
    }

    private void Update()
    {
        Vector3 currentTarget;
        if (target != null)
        {
            currentTarget = target.position;
        }
        else
        {
            currentTarget = FindIdleEyeTarget();
        }
        leftEyeTarget = currentTarget + leftEyeOffset;
        rightEyeTarget = currentTarget + rightEyeOffset;

        AngleChange();
        if (renderViewLines) RenderViewLines();
    }
    
    private Vector3 FindIdleEyeTarget()
    {
        RaycastHit hit;
        if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, viewDistance))
        {
            return hit.point;
        }

        return transform.position + transform.TransformDirection(Vector3.forward) * viewDistance;
    }

    private void AngleChange()
    {
        leftEyeDir = Quaternion.AngleAxis(angleLH, Vector3.up) * Quaternion.AngleAxis(angleLV, Vector3.left) * (leftEyeTarget - leftEye.transform.position); //w przypadku symulacji fizycznych gałek ocznych wektor up zmienić na transform .
        rightEyeDir = Quaternion.AngleAxis(angleRH, Vector3.up) * Quaternion.AngleAxis(angleRV, Vector3.left) * (rightEyeTarget - rightEye.transform.position); //w przypadku symulacji fizycznych gałek ocznych wektor up zmienić na transform .
    }

    private IEnumerator Oscillation()
    {
        while (true)
        {
            if (oscillationActive)
            {
                leftEyeOffset = new Vector3(UnityEngine.Random.Range(-leftEyeMaxOffset.x, leftEyeMaxOffset.x),
                                             UnityEngine.Random.Range(-leftEyeMaxOffset.y, leftEyeMaxOffset.y),
                                             UnityEngine.Random.Range(-leftEyeMaxOffset.z, leftEyeMaxOffset.z));

                rightEyeOffset = new Vector3(UnityEngine.Random.Range(-rightEyeMaxOffset.x, rightEyeMaxOffset.x),
                                              UnityEngine.Random.Range(-rightEyeMaxOffset.y, rightEyeMaxOffset.y),
                                              UnityEngine.Random.Range(-rightEyeMaxOffset.z, rightEyeMaxOffset.z));
            }
            else leftEyeOffset = rightEyeOffset = Vector3.zero;

            yield return new WaitForSeconds(oscillationTime);
        }
    }

    private void RenderViewLines() 
    {
        LeftLaser.SetPosition(0, leftEye.transform.position);
        LeftLaser.SetPosition(1, leftEye.transform.position + leftEyeDir);

        RightLaser.SetPosition(0, rightEye.transform.position);
        RightLaser.SetPosition(1, rightEye.transform.position + rightEyeDir);

        RightDeviation.SetPosition(1, rightEyeTarget);
        RightDeviation.SetPosition(0, rightEye.transform.position);
        LeftDeviation.SetPosition(1, leftEyeTarget);
        LeftDeviation.SetPosition(0, leftEye.transform.position);
    }

    private void LoadEyePos()
    {
        leftEye.transform.localPosition = new Vector3(transform.localPosition.x - eyeDistanceFromCenter, transform.localPosition.y, transform.localPosition.z);
        rightEye.transform.localPosition = new Vector3(transform.localPosition.x + eyeDistanceFromCenter, transform.localPosition.y, transform.localPosition.z);
    }
}