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 Area area;
public List AppearArea = new List();
Vector2 wallRoi;
float origin_height = 0.0f;
[SerializeField]
private RectTransform fakeButton;
[SerializeField]
List specificPositions = new List();
[SerializeField, Range(0, 1)]
float roaming = 0.0f;
float roaming_seed = 0.0f;
[Header("Direct Show Player")]
[SerializeField]
bool isStandbyLoop = true;
public DShowClip standbyClip;
public List triggerClips = new List();
int trigger_clip_index = 0;
[SerializeField]
private DShowMoviePlayer[] players;
public float videoStopTime = 1.5f;
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]
string debugString;
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);
}
foreach (var ply in players)
{
ply.Pause();
ply.Frame = 0;
}
flow = StartCoroutine(Flow());
}
IEnumerator Flow()
{
debugString = "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;
}
debugString = "STANDBY";
// standby
{
state = State.STANDBY;
var player = StatePlayer;
player.Loop = isStandbyLoop;
player.Play();
while (isTriggered == false)
{
debugString = "STANDBY is not triggered";
if (player.Loop == false)
{
if (player.IsPlaying == false)
{
player.Pause();
player.Frame = player.TotalNumFrames;
}
}
yield return null;
}
}
debugString = "TRIGGER";
// trigger
{
state = State.TRIGGER;
var player = StatePlayer;
player.Play();
while (player.IsPlaying)
{
debugString = "TRIGGER is playing";
yield return null;
}
player.Pause();
player.Frame = player.TotalNumFrames;
debugString = "TRIGGER is stopped";
yield return new WaitForSeconds(videoStopTime);
}
debugString = "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;
mat.color = new Color(1, 1, 1, Mathf.Lerp(mat.color.a, alpha, smooth));
}
// 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;
mat.color = new Color(1, 1, 1, Mathf.Lerp(mat.color.a, alpha, smooth));
}
switch (state)
{
case State.STANDBY:
{
if (roaming > 0.0f)
{
UpdateRoamingPosition();
UpdateWallRoiFromPosition();
UpdateButtonPos();
}
}
break;
case State.TRIGGER:
{
}
break;
case State.SLEEP:
{
}
break;
}
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 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 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;
}
}