using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; public class CharacterBehaviour : MonoBehaviour { public float videoStopTime = 1.5f; [Range(0, 15)] public float disappearTime = 5; public Area area; public List AppearArea = new List(); Vector2 wallRoi; float origin_height = 0.0f; [SerializeField] List specificPositions = new List(); [SerializeField, Range(0, 1)] float roaming = 0.0f; float roaming_seed = 0.0f; [SerializeField] private RectTransform fakeButton; [Header("DShow Player")] [SerializeField] bool isStandbyLoop = true; public DShowClip standbyClip; public List triggerClips = new List(); int trigger_clip_index = 0; //[SerializeField] private DShowMoviePlayer[] players; enum State { TRIGGER = 0, STANDBY = 1, SLEEP = 2 } State state = State.SLEEP; DShowMoviePlayer StatePlayer { get { return players[(int)state]; } } MeshRenderer StateRenderer { get { return renderers[(int)state]; } } MeshRenderer[] renderers; bool isTriggered = false; Coroutine flow = null; [SerializeField, Header("Debug")] bool mode = false; [SerializeField] string info; private void Awake() { renderers = GetComponentsInChildren(); if (renderers.Length != 2) Debug.LogWarningFormat("{0} renderer count is {1}", gameObject.name, renderers.Length); //m_meshRender = GetComponent(); //mat = new Material(Shader.Find("Unlit/ColorTransparent")); //m_meshRender.material = mat; origin_height = transform.position.y; InitialiseDSPlayer(); } void InitialiseDSPlayer() { CreateDSPlayer(triggerClips[0]); 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); var standby_scale = renderers[(int)State.STANDBY].transform.localScale; fakeButton.sizeDelta = new Vector2(standby_scale.x, standby_scale.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() { foreach (var rdr in renderers) { rdr.material.mainTextureScale = new Vector2(1, -1); rdr.material.mainTextureOffset = new Vector2(0, -1); } } private void OnEnable() { InitialTouchButton(); ResetFlow(); //standby = true; //isSleep = false; //StartCoroutine(PlayStandbyOnStart()); //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); } private void ResetFlow() { if (flow != null) { StopCoroutine(flow); flow = null; } isTriggered = false; foreach (var rdr in renderers) { rdr.material.color = new Color(1, 1, 1, 0); rdr.material.SetColor("_TintColor", new Color(1, 1, 1, 0)); } foreach (var ply in players) { ply.Pause(); ply.Frame = 0; } flow = StartCoroutine(Flow()); } IEnumerator Flow() { if (mode) info = "setup"; // setup { if (specificPositions.Count > 0) { SetSpecificPos(); } else { RandomAppearWall(); } roaming_seed = Random.Range(0.0f, 1.0f); trigger_clip_index = ++trigger_clip_index % triggerClips.Count; players[(int)State.TRIGGER].VideoAsset = triggerClips[trigger_clip_index]; yield return null; } if (mode) info = "STANDBY"; // standby { state = State.STANDBY; var player = StatePlayer; player.Loop = isStandbyLoop; player.Play(); while (isTriggered == false) { if (mode) info = "STANDBY is not triggered"; if (player.Loop == false) { if (player.IsPlaying == false) { //player.Pause(); //player.Frame = player.TotalNumFrames; if (mode) info = "STANDBY is not triggered and set frame"; } } yield return null; } } if (mode) info = "TRIGGER"; // trigger { state = State.TRIGGER; var player = StatePlayer; player.Play(); while (player.IsPlaying) { if (mode) info = "TRIGGER is playing"; yield return null; } player.Pause(); player.Frame = player.TotalNumFrames; if (mode) info = "TRIGGER is stopped"; yield return new WaitForSeconds(videoStopTime); } if (mode) info = "SLEEP"; // sleep { state = State.SLEEP; yield return new WaitForSeconds(disappearTime); } flow = null; yield return null; } /* IEnumerator PlayStandbyOnStart() { DShowMoviePlayer player = CurrentPlayer; player.Loop = isStandbyLoop; while (!player.IsPlaying) { player.Play(); renderers[STANDBY].material.mainTexture = player.Texture; yield return null; } } */ void Update() { for (int i = 0; i < players.Length; i++) { if (players[i].IsPlaying) { renderers[i].material.mainTexture = players[i].Texture; } } // standby material { float smooth = Time.deltaTime * 2.0f; if (state != State.STANDBY && isStandbyLoop == false) smooth = 1.0f; float alpha = System.Convert.ToInt32(state == State.STANDBY); var mat = renderers[(int)State.STANDBY].material; var col = new Color(1, 1, 1, Mathf.Lerp(mat.color.a, alpha, smooth)); mat.color = col; mat.SetColor("_TintColor", col); } // trigger material { float smooth = Time.deltaTime * 2.0f; if (state == State.TRIGGER) smooth = 1.0f; float alpha = System.Convert.ToInt32(state == State.TRIGGER); var mat = renderers[(int)State.TRIGGER].material; var col = new Color(1, 1, 1, Mathf.Lerp(mat.color.a, alpha, smooth)); mat.color = col; mat.SetColor("_TintColor", col); } switch (state) { case State.STANDBY: { if (roaming > 0.0f) { UpdateRoamingPosition(); UpdateWallRoiFromPosition(); UpdateButtonPos(); } } break; case State.TRIGGER: { } break; case State.SLEEP: { } break; } if (mode) { if (Input.GetKeyDown(KeyCode.R)) { ResetFlow(); } } if (flow == null) ResetFlow(); } 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; float padding = renderers[(int)State.TRIGGER].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 shift = FrozenScreenToWorldSpace.Instance.Position.x; float x = Mathf.Clamp(pos.x + noise, -minmax + shift, minmax + shift); 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 shift = FrozenScreenToWorldSpace.Instance.Position.z; float z = Mathf.Clamp(pos.z + noise, -minmax + shift, minmax + shift); transform.position = new Vector3(pos.x, pos.y, z); } break; } } 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 = renderers[(int)State.TRIGGER].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); var roi = FrozenScreenToWorldSpace.Instance.GetWallRoiFromPosition(area, renderers[(int)State.STANDBY].transform.position); Vector2 newScreenPos = FrozenScreenToWorldSpace.Instance.GetFinalScreenPos(area, roi); 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 (state != State.STANDBY) return; isTriggered = true; } }