using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; public class CharacterBehaviour : MonoBehaviour { [SerializeField] private bool standby = true; [Range(0, 15)] public float disappearTime = 5; public Material mat; public Area area; public List AppearArea = new List(); public Vector2 wallRoi; float origin_height = 0.0f; [SerializeField] private RectTransform fakeButton; public DShowClip standbyClip; public DShowClip triggerClip; [SerializeField] private DShowMoviePlayer[] players; private MeshRenderer m_meshRender; public Color color; private bool isSleep; public float videoStopTime = 1.5f; private const float checktriggerColliderTime = 0.5f; private float triggerColliderTimer; [SerializeField] List specificPositions = new List(); [SerializeField, Range(0, 1)] float roaming = 0.0f; float roaming_seed = 0.0f; private void Awake() { m_meshRender = GetComponent(); mat = new Material(Shader.Find("Unlit/ColorTransparent")); m_meshRender.material = mat; origin_height = transform.position.y; InitialiseDSPlayer(); } void InitialiseDSPlayer() { CreateDSPlayer(triggerClip); CreateDSPlayer(standbyClip); players = GetComponentsInChildren(); } void CreateDSPlayer(DShowClip clip) { GameObject triggerObj = new GameObject(clip.name); triggerObj.transform.parent = this.transform; var player = triggerObj.AddComponent(); player.VideoAsset = clip; player.Load(); } void InitialTouchButton() { if (fakeButton != null) return; GameObject obj = new GameObject(gameObject.name); obj.transform.parent = GameObject.Find("Final Canvas").transform; fakeButton = obj.AddComponent(); fakeButton.anchorMin = new Vector2(0, 0); fakeButton.anchorMax = new Vector2(0, 0); fakeButton.pivot = new Vector2(0.5f, 0.5f); fakeButton.sizeDelta = new Vector2(transform.localScale.x, transform.localScale.y) * FrozenScreenToWorldSpace.Instance.finalPixelsByMeter; fakeButton.anchoredPosition3D = new Vector3(0, 0, 0); fakeButton.localScale = Vector3.one; fakeButton.gameObject.AddComponent(); fakeButton.GetComponent().color = new Color(1, 1, 1, 0); TouchArea touch_area = fakeButton.gameObject.AddComponent(); touch_area.PointerDown.AddListener((data) => { Trigger(data); }); touch_area.PointerDrag.AddListener((data) => { Trigger(data); }); } private void Start() { //standby = true; //isSleep = false; mat.mainTextureScale = new Vector2(1, -1); mat.mainTextureOffset = new Vector2(0, -1); //StartCoroutine(PlayOnStart()); //InitialTouchButton(); //StartCoroutine(RandomPosNoTriggerOther()); } private void OnEnable() { standby = true; isSleep = false; StartCoroutine(PlayOnStart()); InitialTouchButton(); StartCoroutine(RandomPosNoTriggerOther()); color = new Color(1,1,1,0); StartCoroutine(Sleep()); if (fakeButton != null) fakeButton.gameObject.SetActive(true); } private void OnDisable() { if (fakeButton != null) fakeButton.gameObject.SetActive(false); } IEnumerator PlayOnStart() { DShowMoviePlayer player = currentPlayer; player.Loop = true; while (!player.IsPlaying) { player.Play(); mat.mainTexture = player.Texture; yield return null; } } void Update() { if (Input.GetKeyDown(KeyCode.R)) { if (!isTriggerCollider) StartCoroutine(RandomPosNoTriggerOther()); } UpdateMaterial(); if (isSleep == false) { if (standby == false) { CheckPlayFinished(); } else if (standby && roaming > 0.0f) { UpdateRoamingPosition(); UpdateWallRoiFromPosition(); UpdateButtonPos(); } } if (isTriggerCollider) CheckTriggerCollider(); } void CheckTriggerCollider() { triggerColliderTimer -= Time.deltaTime; if (triggerColliderTimer <= 0) isTriggerCollider = false; } void UpdateRoamingPosition() { float noise = Mathf.PerlinNoise(Time.time * 0.4f, roaming_seed) > 0.5f ? 1.0f : -1.0f; noise *= roaming * Time.deltaTime; float padding = transform.localScale.x * 0.5f; Vector3 pos = transform.position; switch (area) { case Area.TopWall: { float minmax = Mathf.Abs(padding - FrozenScreenToWorldSpace.Instance.width * 0.5f); float x = Mathf.Clamp(pos.x + noise, -minmax, minmax); transform.position = new Vector3(x, pos.y, pos.z); } break; case Area.LeftWall: case Area.RightWall: { float minmax = Mathf.Abs(padding - FrozenScreenToWorldSpace.Instance.length * 0.5f); float z = Mathf.Clamp(pos.z + noise, -minmax, minmax); transform.position = new Vector3(pos.x, pos.y, z); } break; } } void UpdateMaterial() { mat.mainTexture = currentPlayer.Texture; mat.SetColor("_Color", color); } void CheckPlayFinished() { if (currentPlayer.IsFinished) { StartCoroutine(Sleep()); } } void RandomAppearWall() { Vector3 newPos = Vector3.zero; area = AppearArea[Random.Range(0, AppearArea.Count)]; Quaternion q = new Quaternion(); if (area == Area.LeftWall) { newPos.x = -FrozenScreenToWorldSpace.Instance.width / 2; q.SetLookRotation(Vector3.left); } if (area == Area.RightWall) { newPos.x = FrozenScreenToWorldSpace.Instance.width / 2; q.SetLookRotation(Vector3.right); } if (area == Area.TopWall) { newPos.z = FrozenScreenToWorldSpace.Instance.length / 2; q.SetLookRotation(Vector3.forward); } transform.rotation = q; transform.position = newPos + FrozenScreenToWorldSpace.Instance.Position; RandomPos(); } void RandomPos() { float minX = transform.localScale.x / 2; #if true switch (area) { case Area.TopWall: wallRoi.x = Random.Range(minX, FrozenScreenToWorldSpace.Instance.width - minX) / FrozenScreenToWorldSpace.Instance.width; break; case Area.LeftWall: case Area.RightWall: wallRoi.x = Random.Range(minX, FrozenScreenToWorldSpace.Instance.length - minX) / FrozenScreenToWorldSpace.Instance.length; break; } #else Vector3 randomPos = transform.localPosition; if (randomPos.x == 0) wallRoi.x = Random.Range(minX, FrozenScreenToWorldSpace.Instance.width - minX) / FrozenScreenToWorldSpace.Instance.width; else wallRoi.x = Random.Range(minX, FrozenScreenToWorldSpace.Instance.length - minX) / FrozenScreenToWorldSpace.Instance.length; #endif wallRoi.y = origin_height / FrozenScreenToWorldSpace.Instance.height; UpdatePos(); UpdateButtonPos(); } void UpdatePos() { #if true Vector3 n_pos = transform.position; switch (area) { case Area.TopWall: n_pos.x = Mathf.Lerp(-FrozenScreenToWorldSpace.Instance.width / 2, FrozenScreenToWorldSpace.Instance.width / 2, wallRoi.x); break; case Area.LeftWall: case Area.RightWall: n_pos.z = Mathf.Lerp(-FrozenScreenToWorldSpace.Instance.length / 2, FrozenScreenToWorldSpace.Instance.length / 2, wallRoi.x); break; } n_pos.y = Mathf.Lerp(0.0f, FrozenScreenToWorldSpace.Instance.height, wallRoi.y); transform.position = n_pos + FrozenScreenToWorldSpace.Instance.Position; #else Vector3 n_pos = transform.localPosition; if (area == Area.TopWall) n_pos.x = Mathf.Lerp(-FrozenScreenToWorldSpace.Instance.width / 2, FrozenScreenToWorldSpace.Instance.width / 2, wallRoi.x); else n_pos.z = Mathf.Lerp(-FrozenScreenToWorldSpace.Instance.length / 2, FrozenScreenToWorldSpace.Instance.length / 2, wallRoi.x); n_pos.y = Mathf.Lerp(0, (float)FrozenScreenToWorldSpace.Instance.height, wallRoi.y); transform.localPosition = n_pos; #endif //SetButtonPos(); } void UpdateButtonPos() { Vector2 newScreenPos = FrozenScreenToWorldSpace.Instance.GetFinalScreenPos(area, wallRoi); fakeButton.anchoredPosition = newScreenPos; } void SetSpecificPos() { int pos_index = Random.Range(0, specificPositions.Count); var dummy = specificPositions[pos_index]; area = dummy.area; transform.position = dummy.transform.position; transform.rotation = dummy.transform.rotation; UpdateWallRoiFromPosition(); UpdateButtonPos(); } void UpdateWallRoiFromPosition() { wallRoi = FrozenScreenToWorldSpace.Instance.GetWallRoiFromPosition(area, transform.position); } private void Trigger(PointerEventData data) { if (!standby || isSleep) return; standby = false; currentPlayer.Play(); mat.mainTexture = currentPlayer.Texture; } void Idle() { standby = true; currentPlayer.Play(); } DShowMoviePlayer currentPlayer { get { return players[System.Convert.ToInt32(standby)]; } } IEnumerator Sleep() { standby = false; isSleep = true; yield return StartCoroutine(WaitVideoStopTimeFadeOut()); yield return new WaitForSeconds(GetDisappear()); yield return StartCoroutine(RandomPosNoTriggerOther()); yield return StartCoroutine(WaitVideoStandbyFadeIn()); isSleep = false; Idle(); } IEnumerator Fade(float targetA) { float value = 0; float origin = color.a; while (value < 1) { value = Mathf.Clamp(value + Time.deltaTime, 0, 1); color.a = Mathf.Lerp(origin, targetA, value); yield return null; } color.a = targetA; } IEnumerator WaitVideoStandbyFadeIn() { standby = true; currentPlayer.Play(); mat.mainTexture = currentPlayer.Texture; yield return StartCoroutine(Fade(1)); } IEnumerator WaitVideoStopTimeFadeOut() { yield return new WaitForSeconds(videoStopTime); yield return StartCoroutine(Fade(0)); currentPlayer.Pause(); currentPlayer.Frame = 0; } public bool isTriggerCollider; private void OnTriggerExit(Collider other) { isTriggerCollider = false; } void OnTriggerStay(Collider other) { isTriggerCollider = true; triggerColliderTimer = checktriggerColliderTime; } private void OnTriggerEnter(Collider other) { isTriggerCollider = true; triggerColliderTimer = checktriggerColliderTime; } public float GetDisappear() { return disappearTime; /* float distime = disappearTime - Random.Range(0, disappearTime / 2); distime = disappearTime * distime - distime * distime + 0.5f * distime; return distime; */ } IEnumerator RandomPosNoTriggerOther() { if (specificPositions.Count > 0) { SetSpecificPos(); yield return null; } else { RandomAppearWall(); yield return new WaitForSeconds(0.1f); while (isTriggerCollider) { RandomAppearWall(); yield return null; } } roaming_seed = Random.Range(0.0f, 1.0f); yield return null; } }