using UnityEngine;
using System.Collections;
public class CameraController {
enum CameraType {
Free,
Focus,
Follow,
}
CameraType m_CameraType = CameraType.Free;
GameObject m_Target = null;
Vector3 m_FocusPosition = Vector3.zero;
float m_FocusTime = 0.0f;
float m_CurrentTime = 0.0f;
Vector3 m_StartCameraPosition = Vector3.zero;
public CameraController() {
}
public void Update() {
switch(m_CameraType) {
case CameraType.Free:
break;
case CameraType.Focus:
UpdateFocus();
break;
case CameraType.Follow:
break;
}
}
public void SetFocus(Vector3 focusPos, float time) {
m_CameraType = CameraType.Focus;
m_FocusTime = time;
m_CurrentTime = 0.0f;
m_StartCameraPosition = Camera.main.transform.position;
Ray ray = new Ray(focusPos, -1.0f*Camera.main.transform.forward);
Plane plane = new Plane(Vector3.up, new Vector3(0, m_StartCameraPosition.y, 0));
float dist = 0.0f;
if(plane.Raycast(ray, out dist)) {
m_FocusPosition = ray.GetPoint(dist);
}
else {
Debug.Break();
m_CameraType = CameraType.Free;
}
}
public void SetFollow(GameObject target) {
m_CameraType = CameraType.Follow;
m_Target = target;
}
void UpdateFocus() {
if(m_CurrentTime > 1.0f) {
m_CameraType = CameraType.Free;
return;
}
m_CurrentTime += Time.deltaTime/m_FocusTime;
Vector3 curPos = (1.0f-m_CurrentTime) * m_StartCameraPosition + m_CurrentTime * m_FocusPosition;
Camera.main.transform.position = curPos;
}
}
public class FlickMain : MonoBehaviour {
GameObject m_3DRoot = null;
Vector3 m_WorldOffset = Vector3.zero;
CameraController m_CameraController = null;
Vector3 m_LastOnPlane = Vector3.zero;
void Awake() {
m_CameraController = new CameraController();
}
void Start () {
m_3DRoot = GameObject.Find("3DRoot");
StartCoroutine(Flick());
}
void Update () {
m_CameraController.Update();
}
void OnGUI() {
if(GUILayout.Button("Title")) {
Application.LoadLevel("Title");
}
}
IEnumerator Flick() {
GameObject target = null;
bool isEnd = false;
int layer = 1<<LayerMask.NameToLayer("Flick");
while(true) {
yield return 0;
while(!isEnd) {
if(Input.GetMouseButtonDown(0)) {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, Mathf.Infinity, layer)) {
target = hit.collider.gameObject;
if(target != null) {
isEnd = true;
target.renderer.material.color = Color.red;
}
}
}
yield return 0;
}
bool isOnPlane = false;
while(Input.GetMouseButton(0)) {
yield return 0;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Plane plane = new Plane(Vector3.up, 0.0f);
Vector3 p = target.transform.position;
float dist = 0.0f;
if(plane.Raycast(ray, out dist)) {
p = ray.GetPoint(dist);
target.transform.position = p;
}
isOnPlane = UpdateLastOnPlane(ref m_LastOnPlane, p);
AdjustSceneOnFlick();
}
target.renderer.material.color = Color.white;
if(!isOnPlane) {
target.transform.position = m_LastOnPlane;
}
float time = 0.0f;
Vector3 spos = m_3DRoot.transform.position;
Vector3 epos = Vector3.zero;
m_CameraController.SetFocus(target.transform.position, 1.0f);
while(time <= 1.0f) {
m_3DRoot.transform.position =
(1.0f-time)*spos + time*epos;
time += Time.deltaTime;
yield return 0;
}
m_3DRoot.transform.position = Vector3.zero;
isEnd = false;
}
}
bool UpdateLastOnPlane(ref Vector3 save, Vector3 pos) {
Ray ray = new Ray(pos+10.0f*Vector3.up, -Vector3.up);
RaycastHit hit;
int layer = 1<<LayerMask.NameToLayer("Plane");
if(Physics.Raycast(ray, out hit, Mathf.Infinity, layer)) {
GameObject obj = hit.collider.gameObject;
if(obj != null) {
save = hit.point;
return true;
}
}
return false;
}
void AdjustSceneOnFlick() {
Vector3 offset = Vector3.zero;
Vector3 mouse_pos = Input.mousePosition;
Vector3 screen_pos = Camera.main.ScreenToViewportPoint(mouse_pos);
if(screen_pos.x < 0.1f) {
offset.x += 0.2f;
}
else if(screen_pos.x > 0.9f) {
offset.x -= 0.2f;
}
if(screen_pos.y < 0.1f) {
offset.z += 0.2f;
}
else if(screen_pos.y > 0.9f) {
offset.z -= 0.2f;
}
if(m_3DRoot) {
m_WorldOffset += offset;
m_LastOnPlane += offset;
m_3DRoot.transform.position += offset;
}
}
}