You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
517 lines
17 KiB
517 lines
17 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.UI;
|
|
|
|
namespace UltraCombos.Frozen
|
|
{
|
|
public class CharacterBehaviour : MonoBehaviour
|
|
{
|
|
public List<State> appearSataes = new List<State>();
|
|
|
|
public float videoStopTime = 1.5f;
|
|
public float disappearTime = 5.0f;
|
|
|
|
public Area area;
|
|
public List<Area> appearAreas = new List<Area>();
|
|
|
|
Vector2 wallRoi;
|
|
float origin_height = 0.0f;
|
|
|
|
[SerializeField]
|
|
List<CharacterDummy> specificPositions = new List<CharacterDummy>();
|
|
|
|
[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<DShowClip> triggerClips = new List<DShowClip>();
|
|
int trigger_clip_index = 0;
|
|
//[SerializeField]
|
|
private DShowMoviePlayer[] players;
|
|
|
|
[Header("Event")]
|
|
[SerializeField]
|
|
UnityEvent onTrigger = new UnityEvent();
|
|
|
|
enum Status
|
|
{
|
|
TRIGGER = 0,
|
|
STANDBY = 1,
|
|
SLEEP = 2
|
|
}
|
|
|
|
Status status = Status.SLEEP;
|
|
DShowMoviePlayer StatePlayer { get { return players[(int)status]; } }
|
|
MeshRenderer StateRenderer { get { return renderers[(int)status]; } }
|
|
|
|
MeshRenderer[] renderers;
|
|
|
|
bool isTriggered = false;
|
|
|
|
Coroutine flow = null;
|
|
|
|
bool is_alive = false;
|
|
const float alive_threshold = 0.5f / 255.0f;
|
|
float alive_value = 0.0f;
|
|
|
|
[SerializeField, Header("Debug")]
|
|
bool mode = false;
|
|
public string info;
|
|
|
|
private void Awake()
|
|
{
|
|
renderers = GetComponentsInChildren<MeshRenderer>();
|
|
if (renderers.Length != 2)
|
|
Debug.LogWarningFormat("{0} renderer count is {1}", gameObject.name, renderers.Length);
|
|
//m_meshRender = GetComponent<MeshRenderer>();
|
|
//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<DShowMoviePlayer>();
|
|
}
|
|
|
|
void CreateDSPlayer(DShowClip clip)
|
|
{
|
|
GameObject triggerObj = new GameObject(clip.name);
|
|
triggerObj.transform.parent = this.transform;
|
|
var player = triggerObj.AddComponent<DShowMoviePlayer>();
|
|
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<RectTransform>();
|
|
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)Status.STANDBY].transform.localScale;
|
|
fakeButton.sizeDelta = new Vector2(standby_scale.x, standby_scale.y) * FrozenScreenToWorldSpace.Instance.finalPixelsByMeter;
|
|
fakeButton.sizeDelta = Vector2.Min(fakeButton.sizeDelta, Vector2.one * 100.0f);
|
|
fakeButton.anchoredPosition3D = new Vector3(0, 0, 0);
|
|
fakeButton.localScale = Vector3.one;
|
|
fakeButton.gameObject.AddComponent<RawImage>();
|
|
fakeButton.GetComponent<RawImage>().color = new Color(1, 1, 1, 0);
|
|
TouchArea touch_area = fakeButton.gameObject.AddComponent<TouchArea>();
|
|
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);
|
|
}
|
|
|
|
public bool Active
|
|
{
|
|
set
|
|
{
|
|
if (value) Activate();
|
|
else Deactivate();
|
|
}
|
|
}
|
|
|
|
public void Activate()
|
|
{
|
|
if (is_alive)
|
|
return;
|
|
is_alive = true;
|
|
gameObject.SetActive(true);
|
|
}
|
|
|
|
public void Deactivate()
|
|
{
|
|
if (is_alive == false)
|
|
return;
|
|
is_alive = 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;
|
|
}
|
|
|
|
if (is_alive)
|
|
{
|
|
flow = StartCoroutine(Flow());
|
|
}
|
|
}
|
|
|
|
IEnumerator Flow()
|
|
{
|
|
if (mode) info = "setup";
|
|
// setup
|
|
{
|
|
if (specificPositions.Count > 0)
|
|
{
|
|
SetSpecificPos();
|
|
}
|
|
else
|
|
{
|
|
RandomAppearWall();
|
|
}
|
|
|
|
roaming_seed = Random.value * 10.0f;
|
|
|
|
trigger_clip_index = ++trigger_clip_index % triggerClips.Count;
|
|
players[(int)Status.TRIGGER].VideoAsset = triggerClips[trigger_clip_index];
|
|
|
|
yield return null;
|
|
}
|
|
|
|
if (mode) info = "STANDBY";
|
|
// standby
|
|
{
|
|
status = Status.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
|
|
{
|
|
onTrigger.Invoke();
|
|
status = Status.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
|
|
{
|
|
status = Status.SLEEP;
|
|
yield return new WaitForSeconds(disappearTime);
|
|
}
|
|
|
|
while (renderers[(int)Status.TRIGGER].material.color.a > 0.5f / 255.0f)
|
|
{
|
|
yield return null;
|
|
}
|
|
|
|
flow = null;
|
|
yield return null;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
alive_value = Mathf.Lerp(alive_value, is_alive ? 1.0f : 0.0f, Time.deltaTime);
|
|
if (is_alive == false && alive_value < alive_threshold)
|
|
{
|
|
alive_value = 0.0f;
|
|
gameObject.SetActive(false);
|
|
}
|
|
|
|
|
|
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 (status != Status.STANDBY && isStandbyLoop == false)
|
|
smooth = 1.0f;
|
|
float alpha = System.Convert.ToInt32(status == Status.STANDBY);
|
|
alpha = Mathf.Min(alpha, alive_value);
|
|
var mat = renderers[(int)Status.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 (status == Status.TRIGGER)
|
|
smooth = 1.0f;
|
|
float alpha = System.Convert.ToInt32(status == Status.TRIGGER);
|
|
alpha = Mathf.Min(alpha, alive_value);
|
|
var mat = renderers[(int)Status.TRIGGER].material;
|
|
var col = new Color(1, 1, 1, Mathf.Lerp(mat.color.a, alpha, smooth));
|
|
mat.color = col;
|
|
mat.SetColor("_TintColor", col);
|
|
}
|
|
|
|
|
|
switch (status)
|
|
{
|
|
case Status.STANDBY:
|
|
{
|
|
if (roaming > 0.0f)
|
|
{
|
|
UpdateRoamingPosition();
|
|
UpdateWallRoiFromPosition();
|
|
UpdateButtonPos();
|
|
}
|
|
}
|
|
break;
|
|
case Status.TRIGGER:
|
|
{
|
|
|
|
}
|
|
break;
|
|
case Status.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, roaming_seed) > 0.5f ? 1.0f : -1.0f;
|
|
noise *= roaming * Time.deltaTime;
|
|
//float padding = transform.localScale.x * 0.5f;
|
|
float padding = renderers[(int)Status.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 = appearAreas[Random.Range(0, appearAreas.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)Status.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)Status.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 (status != Status.STANDBY)
|
|
return;
|
|
|
|
isTriggered = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|