视频路书编辑器完善
This commit is contained in:
parent
17c2a44e40
commit
9f0f42981e
@ -14,6 +14,11 @@ public class MyBuildPostprocessor
|
||||
//System.IO.File.AppendAllText("D:\\test.txt",pathToBuiltProject);
|
||||
#if !(UNITY_IOS || UNITY_ANDROID)
|
||||
var dir = Path.GetDirectoryName(pathToBuiltProject);
|
||||
var managedPath = dir + "\\PowerFun_Data\\Managed";
|
||||
if (!Directory.Exists(managedPath))
|
||||
{
|
||||
Directory.CreateDirectory(managedPath);
|
||||
}
|
||||
File.Copy(dir + "\\PowerFun_Data\\Plugins\\x86_64\\ANT_WrappedLib.dll", dir + "\\PowerFun_Data\\Managed\\ANT_WrappedLib.dll");
|
||||
File.Copy(dir + "\\PowerFun_Data\\Plugins\\x86_64\\DSI_CP210xManufacturing_3_1.dll", dir + "\\PowerFun_Data\\Managed\\DSI_CP210xManufacturing_3_1.dll");
|
||||
File.Copy(dir + "\\PowerFun_Data\\Plugins\\x86_64\\DSI_SiUSBXp_3_1.dll", dir + "\\PowerFun_Data\\Managed\\DSI_SiUSBXp_3_1.dll");
|
||||
|
||||
@ -3692,7 +3692,7 @@ Transform:
|
||||
m_GameObject: {fileID: 1535700487792324436}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: -1, z: 3}
|
||||
m_LocalScale: {x: 0.75, y: 0.75, z: 0.75}
|
||||
m_LocalScale: {x: 0.65, y: 0.65, z: 0.65}
|
||||
m_Children:
|
||||
- {fileID: 5510178270068819320}
|
||||
- {fileID: 3524312104137692172}
|
||||
|
||||
@ -1,33 +1,37 @@
|
||||
243~592:-15,15,0
|
||||
750~908:5,-5,0
|
||||
908~1055:15,-15,0
|
||||
1055~1100:15,-15,0
|
||||
1100~1220:10,0,0
|
||||
1220~1310:10,5,0
|
||||
1330~1695:-5,10,0
|
||||
1899~1925:5,-5,1
|
||||
1925~2340:10,-5,1
|
||||
2524~2790:-5,5,1
|
||||
2960~3120:10,-5,1
|
||||
3120~3300:15,-5,0
|
||||
3300~3555:10,5,0
|
||||
3555~3755:-15,5,0
|
||||
3967~4336:-5,5,0
|
||||
4483~4590:10,-5,0
|
||||
4590~4781:15,-5,0
|
||||
4817~5129:-5,0,0
|
||||
5191~5279:5,0,0
|
||||
5279~5509:10,0,0
|
||||
5630~5900:-10,0,0
|
||||
6578~7641:5,-5,0
|
||||
7838~7919:5,-5,0
|
||||
7919~8050:15,0,0
|
||||
8471~8985:5,0,0
|
||||
9536~9605:-5,0,0
|
||||
9605~9709:-10,0,0
|
||||
10123~10515:5,0,0
|
||||
10500~10700:-5,0,0
|
||||
10807~10834:5,0,0
|
||||
10834~11670:10,-5,0
|
||||
11734~11870:-5,0,0
|
||||
12170~12320:-15,0,0
|
||||
10:10,-5,0,-,-,-
|
||||
243:-15,10,0,-,-,-
|
||||
750:5,-5,1,-,-,-
|
||||
849:30,-10,2,-,-,-
|
||||
1055:15,-15,1,-,-,-
|
||||
1100:10,0,0,-,-,-
|
||||
1220:10,5,0,-,-,-
|
||||
1330:-10,5,0,-,-,-
|
||||
1899:5,-5,1,-,-,-
|
||||
1925:10,-5,1,-,-,-
|
||||
2524:-5,5,1,-,-,-
|
||||
2960:10,-5,1,-,-,-
|
||||
3120:15,-5,0,-,-,-
|
||||
3300:5,5,0,-,-,-
|
||||
3555:-10,5,0,-,-,-
|
||||
3967:-10,5,1,-,-,-
|
||||
4483:10,-5,1,-,-,-
|
||||
4590:15,-5,1,-,-,-
|
||||
4817:-5,0,1,-,-,-
|
||||
5191:5,0,1,-,-,-
|
||||
5279:10,0,1,-,-,-
|
||||
5630:-10,0,0,-,-,-
|
||||
6578:5,-5,0,-,-,-
|
||||
7838:5,-5,1,-,-,-
|
||||
7919:15,0,1,-,-,-
|
||||
8471:10,0,1,-,-,-
|
||||
9536:-5,0,0,-,-,-
|
||||
9605:-10,0,0,-,-,-
|
||||
10123:5,0,0,-,-,-
|
||||
10500:-5,0,0,-,-,-
|
||||
10807:5,0,0,-,-,-
|
||||
10834:15,-5,1,-,-,-
|
||||
11033:5,-5,1,-,-,-
|
||||
11400:5,-5,1,-,-,-
|
||||
11528:5,0,1,-,-,-
|
||||
11734:-5,0,0,-,-,-
|
||||
12170:-25,5,0,-,-,-
|
||||
File diff suppressed because it is too large
Load Diff
@ -71,12 +71,51 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
bone_bottle_2 = transform.Find("bone_cable_20");
|
||||
}
|
||||
|
||||
//人物状态
|
||||
public const int HERO_UP = 0;
|
||||
public const int HERO_RIGHT = 1;
|
||||
public const int HERO_DOWN = 2;
|
||||
public const int HERO_LEFT = 3;
|
||||
|
||||
//人物当前行走的方向状态
|
||||
public int state = 0;
|
||||
//人物移动速度
|
||||
public int moveSpeed = 2;
|
||||
|
||||
void setHeroState(int newState)
|
||||
{
|
||||
//根据当前人物方向与上一次备份的方向计算出模型旋转的角度
|
||||
Vector3 transformValue = new Vector3();
|
||||
//模型移动的位置数值
|
||||
switch (newState)
|
||||
{
|
||||
case HERO_UP:
|
||||
transformValue = Vector3.forward * Time.deltaTime;
|
||||
break;
|
||||
case HERO_DOWN:
|
||||
transformValue = (-Vector3.forward) * Time.deltaTime;
|
||||
break;
|
||||
case HERO_LEFT:
|
||||
transformValue = Vector3.left * Time.deltaTime;
|
||||
break;
|
||||
case HERO_RIGHT:
|
||||
transformValue = (-Vector3.left) * Time.deltaTime;
|
||||
break;
|
||||
}
|
||||
//移动人物
|
||||
transform.Translate(transformValue * moveSpeed, Space.World);
|
||||
state = newState;
|
||||
|
||||
}
|
||||
protected virtual void Update()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
|
||||
#endif
|
||||
timer -= Time.deltaTime;
|
||||
|
||||
CreateHeadImage();
|
||||
|
||||
CharacterControl();
|
||||
Turn();
|
||||
while (timer <= 0)
|
||||
{
|
||||
try
|
||||
@ -90,7 +129,6 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
ComputeRecord();
|
||||
ComputeVideo();
|
||||
RayCastHit();
|
||||
Turn();
|
||||
}
|
||||
ComputeAnimator();//控制动画
|
||||
timer += 1f;
|
||||
@ -104,6 +142,52 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
}
|
||||
|
||||
}
|
||||
private Vector3 rotation = Vector3.zero;
|
||||
private void CharacterControl()
|
||||
{
|
||||
float KeyVertical = Input.GetAxis("Vertical");
|
||||
float KeyHorizontal = Input.GetAxis("Horizontal");
|
||||
|
||||
var delta = 0.2f;
|
||||
var zdelta = 0.1f;
|
||||
|
||||
//控制人物左右倾斜
|
||||
if (Input.GetKey(KeyCode.Q))
|
||||
{
|
||||
rotation.y -= delta;
|
||||
rotation.z += zdelta;
|
||||
transform.DORotate(rotation, 0);
|
||||
}
|
||||
if (Input.GetKey(KeyCode.E))
|
||||
{
|
||||
rotation.y += delta;
|
||||
rotation.z -= zdelta;
|
||||
transform.DORotate(rotation, 0);
|
||||
}
|
||||
//空格键记录当前人物数据
|
||||
if (Input.GetKey(KeyCode.Space))
|
||||
{
|
||||
Debug.Log($"{manager.GetCurrentFrame()}:{transform.rotation.y},{transform.rotation.z},{transform.position.x}");
|
||||
}
|
||||
|
||||
//人物前后左右
|
||||
if (KeyVertical == -1)
|
||||
{
|
||||
setHeroState(HERO_DOWN); //下
|
||||
}
|
||||
else if (KeyVertical == 1)
|
||||
{
|
||||
setHeroState(HERO_UP); //上
|
||||
}
|
||||
if (KeyHorizontal == 1)
|
||||
{
|
||||
setHeroState(HERO_RIGHT); //右
|
||||
}
|
||||
else if (KeyHorizontal == -1)
|
||||
{
|
||||
setHeroState(HERO_LEFT); //左
|
||||
}
|
||||
}
|
||||
|
||||
//人物碰撞
|
||||
void OnCollisionEnter(Collision collision)
|
||||
@ -111,7 +195,7 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
|
||||
}
|
||||
|
||||
void RayCastHit()
|
||||
void RayCastHit()
|
||||
{
|
||||
Vector3 pos = transform.position;
|
||||
Ray ray = new Ray(pos, new Vector3(0, 0, 1));
|
||||
@ -132,104 +216,56 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
animator.SetFloat("speed", (float)speed);
|
||||
animator.SetFloat("grade", (float)currentSlope);
|
||||
animator.SetFloat("power", (float)power);
|
||||
animator.SetFloat("bearing", bearing);
|
||||
//播放喝水和回头的动画
|
||||
var headBack = ticks % 60 == 0 && speed > 0;
|
||||
var drink = ticks % 125 == 0 && speed > 0;
|
||||
animator.SetBool("headBack", headBack);
|
||||
animator.SetBool("drinking", drink);
|
||||
}
|
||||
}
|
||||
protected virtual int GetCurrentFrame()
|
||||
{
|
||||
protected virtual int GetCurrentFrame()
|
||||
{
|
||||
return manager.GetCurrentFrame();
|
||||
}
|
||||
private bool animated = false;
|
||||
private float offset = 0;
|
||||
private Vector3 rotation = Vector3.zero;
|
||||
protected CustomRange currentRange { get; set; }
|
||||
//控制角色进行向左或向右
|
||||
|
||||
private CustomRange pre;
|
||||
private CustomRange next;
|
||||
protected virtual void Turn()
|
||||
{
|
||||
//控制人物的转向
|
||||
var currentFrame = GetCurrentFrame();
|
||||
currentRange = manager.mockDirection.Where(c => c.Start < currentFrame && c.End > currentFrame).FirstOrDefault();
|
||||
if (currentRange != null)
|
||||
{
|
||||
bearing = currentRange.RotationY;
|
||||
rotation.y = currentRange.RotationY;
|
||||
rotation.z = currentRange.RotationZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotation.y = 0;
|
||||
rotation.z = 0;
|
||||
bearing = 0;
|
||||
}
|
||||
|
||||
var headBack = ticks % 60 == 0 && speed > 0 && bearing == 0;
|
||||
var drink = ticks % 125 == 0 && speed > 0 && bearing == 0;
|
||||
var config = manager.mockDirection;
|
||||
|
||||
animator.SetFloat("bearing", bearing);
|
||||
animator.SetBool("headBack", headBack);
|
||||
animator.SetBool("drinking", drink);
|
||||
pre = config[0];
|
||||
next = config[0];
|
||||
|
||||
var waiting = ratio == 0 ? 1 : 1 / ratio;
|
||||
//直角拐弯
|
||||
if (Math.Abs(bearing) > 30)
|
||||
for (int i = 0; i < config.Count; i++)
|
||||
{
|
||||
if (!animated)
|
||||
if (config[i].KeyFrame >= currentFrame)
|
||||
{
|
||||
animated = true;
|
||||
var tween = transform.DORotate(new Vector3(0, bearing, -bearing/5), waiting);
|
||||
tween.onComplete += () =>
|
||||
{
|
||||
var zoffset = bearing / 10.5f;
|
||||
var doMoveX = transform.DOMoveX(transform.position.x + zoffset, waiting);
|
||||
doMoveX.onComplete += () =>
|
||||
{
|
||||
offset = -zoffset;
|
||||
};
|
||||
};
|
||||
tween.SetEase(Ease.InOutSine).SetLoops(2, LoopType.Incremental);
|
||||
pre = i > 0 ? config[i - 1] : config[i];
|
||||
next = config[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//直角拐弯回正
|
||||
if (offset != 0)
|
||||
{
|
||||
var cpoffset = offset;
|
||||
transform.DORotate(new Vector3(0, bearing, 0), 1.2f * waiting).onComplete += () =>
|
||||
{
|
||||
transform.DOMoveX(transform.position.x + cpoffset, 1.2f * waiting).onComplete += () =>
|
||||
{
|
||||
animated = false;
|
||||
};
|
||||
};
|
||||
offset = 0;
|
||||
}
|
||||
//正常拐弯
|
||||
else
|
||||
{
|
||||
transform.DORotate(rotation, 0.6f);
|
||||
}
|
||||
}
|
||||
}
|
||||
Vector3 current;
|
||||
Vector3 forward;
|
||||
//0-90 右转弯 -90-0左转弯
|
||||
protected virtual void TurnAround()
|
||||
{
|
||||
StartCoroutine(MoveTo());
|
||||
|
||||
var p = new Vector3(0, pre.RotationY, pre.RotationZ);
|
||||
var q = new Vector3(0, next.RotationY, next.RotationZ);
|
||||
var t = (float)(currentFrame - pre.KeyFrame) / (float)(next.KeyFrame - pre.KeyFrame);
|
||||
var rt = Vector3.Slerp(p, q, t);
|
||||
|
||||
transform.DORotate(rt, 0, RotateMode.Fast);
|
||||
|
||||
//控制人物的前后左右
|
||||
|
||||
var l = new Vector3(pre.PositionX, pre.PositionY, pre.PositionZ);
|
||||
var s = new Vector3(next.PositionX, next.PositionY, next.PositionZ);
|
||||
var pos = Vector3.Slerp(l,s, t);
|
||||
transform.DOMove(pos,0);
|
||||
|
||||
//TODO:控制光线
|
||||
}
|
||||
|
||||
protected virtual IEnumerator MoveTo()
|
||||
{
|
||||
float t = 0;
|
||||
while (t < 1)
|
||||
{
|
||||
t += Time.deltaTime;
|
||||
Vector3 v = Vector3.Lerp(current, forward, t);
|
||||
current = v;
|
||||
transform.DORotate(v, 0);
|
||||
yield return new WaitForEndOfFrame();
|
||||
}
|
||||
}
|
||||
//计算人物当前属性
|
||||
protected virtual void ComputePlayer()
|
||||
{
|
||||
@ -252,7 +288,9 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 current { get; set; }
|
||||
Vector3 forward { get; set; }
|
||||
//计算当前人物的经纬度
|
||||
protected virtual void Forward()
|
||||
{
|
||||
try
|
||||
@ -260,30 +298,13 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
if (mapData == null)
|
||||
mapData = manager.GetMapData();
|
||||
currentlatLon = manager.Along(totalDistance % mapData.TotalDistance);
|
||||
////根据人物速度设置人物距离摄像头远近
|
||||
//if (speed > 20 && speed < 30)
|
||||
//{
|
||||
// transform.DOMoveZ(3, 1f);
|
||||
//}
|
||||
//else if (speed > 30 && speed < 40)
|
||||
//{
|
||||
// transform.DOMoveZ(3.5f, 1f);
|
||||
//}
|
||||
//else if (speed > 40)
|
||||
//{
|
||||
// transform.DOMoveZ(4, 1f);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// transform.DOMoveZ(3, 1f);
|
||||
//}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
protected float ratio = 1;
|
||||
protected float ratio = 1;//视频播放速率
|
||||
|
||||
protected virtual void ComputeVideo()
|
||||
{
|
||||
@ -369,7 +390,7 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//显示人物海拔图的头像
|
||||
public void CreateHeadImage()
|
||||
{
|
||||
if (head == null)
|
||||
|
||||
@ -24,28 +24,38 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class CustomRange
|
||||
{
|
||||
public int KeyFrame { get; set; }//帧数
|
||||
public int Start { get; set; }//起始帧
|
||||
public int End { get; set; }//结束帧
|
||||
public int PositionX { get; set; }
|
||||
public int PositionY { get; set; }
|
||||
public int PositionZ { get; set; }
|
||||
public int RotationY { get; set; }
|
||||
public int RotationZ { get; set; }
|
||||
public int ShadowDirection { get; set; }
|
||||
public float PositionX { get; set; }
|
||||
public float PositionY { get; set; }
|
||||
public float PositionZ { get; set; }
|
||||
public float RotationY { get; set; }
|
||||
public float RotationZ { get; set; }
|
||||
public float LightY { get; set; }
|
||||
|
||||
private const float defaultRotationY = 0;
|
||||
private const float defaultRotationZ = 0;
|
||||
private const float defaultPositionX = 0;
|
||||
private const float defaultPositionY = -1;
|
||||
private const float defaultPositionZ = 3;
|
||||
private const float defaultLightY = 0;
|
||||
|
||||
public static CustomRange Read(string s)
|
||||
{
|
||||
//243~573:-15,13,12
|
||||
// - 代表默认值
|
||||
//KeyFrame:RotationY,RotationZ,PositionX,PositionY,PositionZ,LightY
|
||||
var result = s.Split(':');
|
||||
var range = result[0].Split('~');
|
||||
var v = result[1].Split(',');
|
||||
CustomRange r = new CustomRange()
|
||||
{
|
||||
Start = Convert.ToInt32(range[0]),
|
||||
End = Convert.ToInt32(range[1]),
|
||||
RotationY = Convert.ToInt32(v[0]),
|
||||
RotationZ = Convert.ToInt32(v[1]),
|
||||
PositionX = Convert.ToInt32(v[2]),
|
||||
KeyFrame = Convert.ToInt32(result[0]),
|
||||
RotationY = v[0].Equals("-") ? defaultRotationY : (float)Convert.ToDouble(v[0]),
|
||||
RotationZ = v[1].Equals("-") ? defaultRotationZ : (float)Convert.ToDouble(v[1]),
|
||||
PositionX = v[2].Equals("-") ? defaultPositionX : (float)Convert.ToDouble(v[2]),
|
||||
PositionY = v[3].Equals("-") ? defaultPositionY : (float)Convert.ToDouble(v[3]),
|
||||
PositionZ = v[4].Equals("-") ? defaultPositionZ : (float)Convert.ToDouble(v[4]),
|
||||
LightY = v[5].Equals("-") ? defaultLightY : (float)Convert.ToDouble(v[5]),
|
||||
};
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -48,14 +48,6 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
protected override void Turn()
|
||||
{
|
||||
base.Turn();
|
||||
if (currentRange != null)
|
||||
{
|
||||
transform.DOMoveX(currentRange.PositionX, 0.8f);
|
||||
}
|
||||
else
|
||||
{
|
||||
transform.DOMoveX(1, 0.8f);
|
||||
}
|
||||
}
|
||||
protected override void ComputePlayer()
|
||||
{
|
||||
|
||||
@ -19,9 +19,9 @@ public class MultiTips:PFUIText
|
||||
if (result.result)
|
||||
{
|
||||
tips = result.data.ToArray();
|
||||
random = new System.Random();
|
||||
currentIndex = random.Next(0, tips.Length);
|
||||
}
|
||||
random = new System.Random();
|
||||
currentIndex = random.Next(0, tips.Length);
|
||||
SetText();
|
||||
}
|
||||
// Start is called before the first frame update
|
||||
|
||||
488
Assets/TestVideoController.cs
Normal file
488
Assets/TestVideoController.cs
Normal file
@ -0,0 +1,488 @@
|
||||
using DG.Tweening;
|
||||
using RenderHeads.Media.AVProVideo;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
using Assets.Scripts.Scenes.VideoRide;
|
||||
using System.Reflection;
|
||||
using UnityEngine.UI;
|
||||
using Assets.Scripts;
|
||||
|
||||
public class TestVideoController : MonoBehaviour
|
||||
{
|
||||
|
||||
public Transform Player;
|
||||
|
||||
public GameObject QuitBtn;
|
||||
|
||||
public GameObject PauseBtn;
|
||||
|
||||
public GameObject CancelBtn;
|
||||
|
||||
public Transform Light;
|
||||
|
||||
public Transform FrameContent;
|
||||
|
||||
public GameObject FrameBtnPrefab;
|
||||
|
||||
public GameObject PreviewBtn;
|
||||
|
||||
public GameObject SaveBtn;
|
||||
|
||||
public GameObject ResetBtn;
|
||||
|
||||
public GameObject DeleteBtn;
|
||||
|
||||
public MediaPlayer mediaPlayer;
|
||||
|
||||
public Text Frametext;
|
||||
|
||||
private Dictionary<int, string> list = new Dictionary<int, string>();
|
||||
Vector3 originPos = new Vector3(0, -1, 3);
|
||||
Vector3 originRotation = Vector3.zero;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
lightRotation = new Vector3(50f,-45,0);
|
||||
InitConfig();
|
||||
UIManager.AddEvent(QuitBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, (e) =>
|
||||
{
|
||||
Application.Quit();
|
||||
});
|
||||
UIManager.AddEvent(PauseBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, (e) =>
|
||||
{
|
||||
PlayOrPause();
|
||||
});
|
||||
UIManager.AddEvent(PreviewBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, (e) =>
|
||||
{
|
||||
BuildList();
|
||||
isPlay = true;
|
||||
mediaPlayer.Control.SeekFast(0);
|
||||
mediaPlayer.Play();
|
||||
});
|
||||
UIManager.AddEvent(slider.gameObject, UnityEngine.EventSystems.EventTriggerType.Drag, (e) =>
|
||||
{
|
||||
OnTimeSliderDrag();
|
||||
});
|
||||
UIManager.AddEvent(SaveBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, (e) =>
|
||||
{
|
||||
DoRecord();
|
||||
});
|
||||
UIManager.AddEvent(ResetBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, (e) =>
|
||||
{
|
||||
Player.DOMove(originPos,0);
|
||||
Player.DORotate(originRotation, 0);
|
||||
});
|
||||
UIManager.AddEvent(CancelBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, (e) =>
|
||||
{
|
||||
var k = mockRange.Where(c => c.KeyFrame == currentFrame).FirstOrDefault();
|
||||
if (k != null)
|
||||
{
|
||||
Player.DOMove(new Vector3(k.PositionX, k.PositionY, k.PositionZ), 0);
|
||||
Player.DORotate(new Vector3(0, k.RotationY, k.RotationZ), 0);
|
||||
}
|
||||
});
|
||||
UIManager.AddEvent(DeleteBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, (e) =>
|
||||
{
|
||||
DeleteFrame(currentFrame);
|
||||
});
|
||||
}
|
||||
public Text PlayBtnText;
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
Frametext.text = $"当前视频帧数:{GetCurrentFrame()}";
|
||||
//视频播放时间
|
||||
TimeRange timelineRange = GetTimelineRange();
|
||||
double time = mediaPlayer.Control.GetCurrentTime();
|
||||
sliderText.text = $"{ Assets.Scenes.Ride.Scripts.Helper.FormatTicks((int)Math.Floor(time))}/{Assets.Scenes.Ride.Scripts.Helper.FormatTicks((int)Math.Floor(timelineRange.duration))}";
|
||||
if (timelineRange.duration != 0)
|
||||
{
|
||||
slider.value = (float)(time / timelineRange.duration);
|
||||
}
|
||||
//键盘输入
|
||||
CharacterControl();
|
||||
//计算当前帧数在哪个区段
|
||||
ComputeCurrentFrame();
|
||||
//人物控制
|
||||
if (isPlay)
|
||||
{
|
||||
Turn();
|
||||
}
|
||||
//暂停或播放
|
||||
var isPause = mediaPlayer.Control.IsPaused();
|
||||
ResetBtn.SetActive(isPause);
|
||||
if (!isPause)
|
||||
{
|
||||
CancelBtn.SetActive(false);
|
||||
DeleteBtn.SetActive(false);
|
||||
}
|
||||
PlayBtnText.text = isPause ? "播放" : "暂停";
|
||||
}
|
||||
|
||||
public int currentFrame { get; set; }
|
||||
|
||||
public void PlayToFrame(int frame)
|
||||
{
|
||||
var config = mockRange.Where(c => c.KeyFrame == frame).FirstOrDefault();
|
||||
if (config != null)
|
||||
{
|
||||
CancelBtn.SetActive(true);
|
||||
DeleteBtn.SetActive(true);
|
||||
currentFrame = frame;
|
||||
SeekToFrame(frame);
|
||||
mediaPlayer.Pause();
|
||||
isPlay = false;
|
||||
var rotation = new Vector3(0, config.RotationY, config.RotationZ);
|
||||
Player.DORotate(rotation, 0);
|
||||
var pos = new Vector3(config.PositionX, config.PositionY, config.PositionZ);
|
||||
Player.DOMove(pos, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private string ConfigPath = Application.streamingAssetsPath + "/newdirection.txt";
|
||||
//初始化配置
|
||||
private void InitConfig()
|
||||
{
|
||||
var text = File.ReadAllText(ConfigPath);
|
||||
var arr = text.Replace("\r\n", " ").Split(' ');
|
||||
foreach (var item in arr)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item))
|
||||
{
|
||||
int key = Convert.ToInt32(item.Split(':')[0]);
|
||||
list.Add(key, item);
|
||||
}
|
||||
}
|
||||
BuildList();
|
||||
if (mockRange.Count > 0)
|
||||
{
|
||||
pre = mockRange[0];
|
||||
next = mockRange[0];
|
||||
}
|
||||
}
|
||||
private void DeleteFrame(int frame)
|
||||
{
|
||||
//删除当前帧数
|
||||
var s = mockRange.Where(c => c.KeyFrame == frame).FirstOrDefault();
|
||||
if (s != null)
|
||||
{
|
||||
mockRange.Remove(s);
|
||||
}
|
||||
|
||||
if (list.ContainsKey(frame))
|
||||
{
|
||||
list.Remove(frame);
|
||||
}
|
||||
|
||||
//回到上一帧
|
||||
var l = mockRange.OrderBy(c => c.KeyFrame).ToList();
|
||||
var btnList = FindObjectsOfType<TestVideoFrameButton>();
|
||||
|
||||
var needRemove = btnList.Where(c => c.Frame == frame).FirstOrDefault();
|
||||
if (needRemove != null)
|
||||
{
|
||||
needRemove.Destroy();
|
||||
}
|
||||
|
||||
var nextFrame = 0;
|
||||
foreach (var item in l)
|
||||
{
|
||||
if (item.KeyFrame < frame)
|
||||
{
|
||||
nextFrame = item.KeyFrame;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var btn = btnList.Where(c => c.Frame == nextFrame).FirstOrDefault();
|
||||
if (btn != null)
|
||||
{
|
||||
btn.SelectFrame(nextFrame);
|
||||
}
|
||||
//同步到txt
|
||||
Save();
|
||||
}
|
||||
private void BuildList()
|
||||
{
|
||||
var l = list.OrderBy(c => c.Key);
|
||||
mockRange.Clear();
|
||||
Utils.DestroyChildren(FrameContent);
|
||||
foreach (var item in l)
|
||||
{
|
||||
mockRange.Add(CustomRange.Read(item.Value));
|
||||
var btn = Instantiate<GameObject>(FrameBtnPrefab, FrameContent);
|
||||
btn.SetActive(true);
|
||||
btn.GetComponent<TestVideoFrameButton>().SetInfo(item.Key);
|
||||
}
|
||||
}
|
||||
|
||||
private bool isPlay { get; set; } = true;
|
||||
private List<CustomRange> mockRange = new List<CustomRange>();
|
||||
|
||||
private CustomRange pre;
|
||||
private CustomRange next;
|
||||
private void ComputeCurrentFrame()
|
||||
{
|
||||
var currentFrame = GetCurrentFrame();
|
||||
var config = mockRange;
|
||||
if (config.Count == 0)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < config.Count; i++)
|
||||
{
|
||||
if (config[i].KeyFrame >= currentFrame)
|
||||
{
|
||||
pre = i > 0 ? config[i - 1] : config[i];
|
||||
next = config[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void Turn()
|
||||
{
|
||||
var currentFrame = GetCurrentFrame();
|
||||
//控制人物的转向
|
||||
var p = new Vector3(0, pre.RotationY, pre.RotationZ);
|
||||
var q = new Vector3(0, next.RotationY, next.RotationZ);
|
||||
var t = next.KeyFrame - pre.KeyFrame == 0? 1 : (float)(currentFrame - pre.KeyFrame) / (float)(next.KeyFrame - pre.KeyFrame);
|
||||
var rt = Vector3.Lerp(p, q, t);
|
||||
Player.DORotate(rt, 0, RotateMode.Fast);
|
||||
//控制人物的前后左右
|
||||
var l = new Vector3(pre.PositionX, pre.PositionY, pre.PositionZ);
|
||||
var s = new Vector3(next.PositionX, next.PositionY, next.PositionZ);
|
||||
var pos = Vector3.Lerp(l, s, t);
|
||||
Player.DOMove(pos, 0);
|
||||
//控制光线
|
||||
var z = new Vector3(50, pre.LightY, 0);
|
||||
var c = new Vector3(50, next.LightY, 0);
|
||||
var zc = Vector3.Lerp(z, c, t);
|
||||
Light.DORotate(zc, 0);
|
||||
}
|
||||
public Slider slider;
|
||||
public Text sliderText;
|
||||
private void OnTimeSliderDrag()
|
||||
{
|
||||
if (mediaPlayer && mediaPlayer.Control != null)
|
||||
{
|
||||
TimeRange timelineRange = GetTimelineRange();
|
||||
double time = timelineRange.startTime + ( slider.value*timelineRange.duration);
|
||||
mediaPlayer.Control.Seek(time);
|
||||
}
|
||||
}
|
||||
|
||||
private TimeRange GetTimelineRange()
|
||||
{
|
||||
if (mediaPlayer.Info != null)
|
||||
{
|
||||
return Helper.GetTimelineRange(mediaPlayer.Info.GetDuration(), mediaPlayer.Control.GetSeekableTimes());
|
||||
}
|
||||
return new TimeRange();
|
||||
}
|
||||
|
||||
private void SeekToFrame(int frame)
|
||||
{
|
||||
mediaPlayer.Control.SeekToFrame(frame);
|
||||
}
|
||||
private int GetCurrentFrame()
|
||||
{
|
||||
return mediaPlayer.Control.GetCurrentTimeFrames();
|
||||
}
|
||||
|
||||
private int GetPreFrame(int frame)
|
||||
{
|
||||
return mediaPlayer.Control.GetCurrentTimeFrames();
|
||||
}
|
||||
private Vector3 rotation = Vector3.zero;
|
||||
private Vector3 lightRotation;
|
||||
private void CharacterControl()
|
||||
{
|
||||
var delta = 0.2f;
|
||||
var zdelta = 0.1f;
|
||||
//控制太阳
|
||||
if (Input.GetKey(KeyCode.Z))
|
||||
{
|
||||
//lightRotation.x -= delta;
|
||||
lightRotation.y += zdelta;
|
||||
Light.DORotate(lightRotation, 0);
|
||||
isPlay = false;
|
||||
}
|
||||
if (Input.GetKey(KeyCode.C))
|
||||
{
|
||||
// lightRotation.x += delta;
|
||||
lightRotation.y -= zdelta;
|
||||
Light.DORotate(lightRotation, 0);
|
||||
isPlay = false;
|
||||
}
|
||||
//控制人物方向
|
||||
if (Input.GetKey(KeyCode.Q))
|
||||
{
|
||||
rotation.y -= delta;
|
||||
Player.DORotate(rotation, 0);
|
||||
isPlay = false;
|
||||
}
|
||||
if (Input.GetKey(KeyCode.E))
|
||||
{
|
||||
rotation.y += delta;
|
||||
Player.DORotate(rotation, 0);
|
||||
isPlay = false;
|
||||
}
|
||||
//控制人物左右倾斜
|
||||
if (Input.GetKey(KeyCode.J))
|
||||
{
|
||||
rotation.z += zdelta;
|
||||
Player.DORotate(rotation, 0);
|
||||
isPlay = false;
|
||||
}
|
||||
if (Input.GetKey(KeyCode.K))
|
||||
{
|
||||
rotation.z -= zdelta;
|
||||
Player.DORotate(rotation, 0);
|
||||
isPlay = false;
|
||||
}
|
||||
//空格键记录当前人物数据
|
||||
if (Input.GetKeyDown(KeyCode.Space))
|
||||
{
|
||||
PlayOrPause();
|
||||
}
|
||||
//人物前后左右
|
||||
if (Input.GetKey(KeyCode.S))
|
||||
{
|
||||
setHeroState(HERO_DOWN); //下
|
||||
}
|
||||
else if (Input.GetKey(KeyCode.W))
|
||||
{
|
||||
setHeroState(HERO_UP); //上
|
||||
}
|
||||
if (Input.GetKey(KeyCode.D))
|
||||
{
|
||||
setHeroState(HERO_RIGHT); //右
|
||||
}
|
||||
else if (Input.GetKey(KeyCode.A))
|
||||
{
|
||||
setHeroState(HERO_LEFT); //左
|
||||
}
|
||||
//控制视频播放进度
|
||||
if (Input.GetKey(KeyCode.LeftArrow))
|
||||
{
|
||||
var frame = GetCurrentFrame()-1;
|
||||
SeekToFrame(frame);
|
||||
}
|
||||
if (Input.GetKey(KeyCode.RightArrow))
|
||||
{
|
||||
var frame = GetCurrentFrame() + 1;
|
||||
SeekToFrame(frame);
|
||||
}
|
||||
}
|
||||
private void PlayOrPause()
|
||||
{
|
||||
if (mediaPlayer.Control.IsPaused())
|
||||
{
|
||||
isPlay = true;
|
||||
mediaPlayer.Play();
|
||||
}
|
||||
else
|
||||
{
|
||||
isPlay = false;
|
||||
mediaPlayer.Pause();
|
||||
}
|
||||
}
|
||||
private void DoRecord()
|
||||
{
|
||||
Save();
|
||||
BuildList();
|
||||
//回到上一个节点
|
||||
if (pre != null)
|
||||
{
|
||||
mediaPlayer.Control.SeekToFrame(pre.KeyFrame);
|
||||
}
|
||||
isPlay = true;
|
||||
mediaPlayer.Play();
|
||||
}
|
||||
|
||||
private void Save()
|
||||
{
|
||||
var key = GetCurrentFrame();
|
||||
//获取人物inpector面板的rotation值
|
||||
Vector3 vect3 = Vector3.zero;
|
||||
Vector3 vect = Vector3.zero;
|
||||
MethodInfo mth = typeof(Transform).GetMethod("GetLocalEulerAngles", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
PropertyInfo pi = typeof(Transform).GetProperty("rotationOrder", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
object rotationOrder = null;
|
||||
object lightRotationOrder = null;
|
||||
if (pi != null)
|
||||
{
|
||||
rotationOrder = pi.GetValue(Player, null);
|
||||
lightRotationOrder= pi.GetValue(Light, null);
|
||||
}
|
||||
if (mth != null)
|
||||
{
|
||||
object retVector3 = mth.Invoke(Player, new object[] { rotationOrder });
|
||||
vect3 = (Vector3)retVector3;
|
||||
|
||||
object retVector = mth.Invoke(Light, new object[] { lightRotationOrder });
|
||||
vect = (Vector3)retVector;
|
||||
}
|
||||
//保存记录
|
||||
var s = $"{key}:{ Math.Round(vect3.y, 3)},{ Math.Round(vect3.z, 3)},{Math.Round(Player.position.x,3)},{Math.Round(Player.position.y,3)},{Math.Round(Player.position.z,3)},{Math.Round(vect.y,3)}";
|
||||
if (list.ContainsKey(key))
|
||||
{
|
||||
list[key] = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(key, s);
|
||||
}
|
||||
var coll = list.OrderBy(c => c.Key);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (var item in coll)
|
||||
{
|
||||
sb.AppendLine(item.Value);
|
||||
}
|
||||
File.WriteAllText(ConfigPath, sb.ToString());
|
||||
}
|
||||
//人物状态
|
||||
public const int HERO_UP = 0;
|
||||
public const int HERO_RIGHT = 1;
|
||||
public const int HERO_DOWN = 2;
|
||||
public const int HERO_LEFT = 3;
|
||||
|
||||
//人物当前行走的方向状态
|
||||
public int state = 0;
|
||||
//人物移动速度
|
||||
public int moveSpeed = 2;
|
||||
void setHeroState(int newState)
|
||||
{
|
||||
isPlay = false;
|
||||
//根据当前人物方向与上一次备份的方向计算出模型旋转的角度
|
||||
Vector3 transformValue = new Vector3();
|
||||
//模型移动的位置数值
|
||||
switch (newState)
|
||||
{
|
||||
case HERO_UP:
|
||||
transformValue = Vector3.forward * Time.deltaTime;
|
||||
break;
|
||||
case HERO_DOWN:
|
||||
transformValue = (-Vector3.forward) * Time.deltaTime;
|
||||
break;
|
||||
case HERO_LEFT:
|
||||
transformValue = Vector3.left * Time.deltaTime;
|
||||
break;
|
||||
case HERO_RIGHT:
|
||||
transformValue = (-Vector3.left) * Time.deltaTime;
|
||||
break;
|
||||
}
|
||||
////移动人物
|
||||
Player.Translate(transformValue * moveSpeed, Space.World);
|
||||
state = newState;
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/TestVideoController.cs.meta
Normal file
11
Assets/TestVideoController.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bf7b98eb98643b43b88eb78adee7475
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
47
Assets/TestVideoFrameButton.cs
Normal file
47
Assets/TestVideoFrameButton.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class TestVideoFrameButton : MonoBehaviour
|
||||
{
|
||||
|
||||
public int Frame { get; private set; }
|
||||
private TestVideoController manager { get; set; }
|
||||
|
||||
public GameObject Bg;
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
manager = FindObjectOfType<TestVideoController>();
|
||||
|
||||
UIManager.AddEvent(gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, (e) =>
|
||||
{
|
||||
SelectFrame(Frame);
|
||||
});
|
||||
}
|
||||
|
||||
public void SelectFrame(int frame)
|
||||
{
|
||||
manager.PlayToFrame(Frame);
|
||||
var list = FindObjectsOfType<TestVideoFrameButton>();
|
||||
foreach (var item in list)
|
||||
{
|
||||
item.SetBg(item.Frame == Frame);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBg(bool active)
|
||||
{
|
||||
Bg.SetActive(active);
|
||||
}
|
||||
|
||||
public void SetInfo(int frame)
|
||||
{
|
||||
this.Frame = frame;
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
gameObject.Destroy();
|
||||
}
|
||||
}
|
||||
11
Assets/TestVideoFrameButton.cs.meta
Normal file
11
Assets/TestVideoFrameButton.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85e9b049aa321b341a130483a7a86b7e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
x
Reference in New Issue
Block a user