先修复一下,错误的场景 删除不必要的钓场资产 修复into场景 update:更新meta文件,修复报错 update:修复资源 修复第一章节建造 修复建造第三章 update:删除多余内容 update:更新README.md update:还原图标 update:更新README update:更新配置
511 lines
19 KiB
C#
511 lines
19 KiB
C#
using asap.core;
|
|
using cfg;
|
|
using DG.Tweening;
|
|
using Game;
|
|
using GameCore;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.AddressableAssets;
|
|
|
|
public class CrossbowCameraMove : MonoBehaviour
|
|
{
|
|
Vector3 _curMousePos;
|
|
Vector3 _offsetEuler;
|
|
Quaternion targetRotation;
|
|
//屏幕拖动比例
|
|
float dragCameraScale = 0.03f;
|
|
private Vector3 initialRotation;
|
|
bool isFinish;
|
|
Transform handRoot;
|
|
HandController HandController;
|
|
GameObject handAB;
|
|
Crossbow crossbow;
|
|
CrossbowArrow crossbowArrow;
|
|
AquariumCameraManager manager;
|
|
int state = 0;//0:未开始 1:射击结束 2:收紧线 3:逃脱
|
|
Vector2 cameraOffset;
|
|
|
|
public FishMovement guide;
|
|
|
|
|
|
private void Awake()
|
|
{
|
|
crossbow = GetComponentInChildren<Crossbow>();
|
|
crossbowArrow = GetComponentInChildren<CrossbowArrow>();
|
|
crossbowArrow.gameObject.SetActive(false);
|
|
crossbow.fishingLineRenderer.enabled = false;
|
|
crossbowPos = crossbow.animator.transform.localPosition;
|
|
}
|
|
public void Init(AquariumCameraManager aquariumCameraManager, Transform handRoot, Vector2 cameraOffset, FishMovement guide)
|
|
{
|
|
this.manager = aquariumCameraManager;
|
|
this.cameraOffset = cameraOffset;
|
|
this.handRoot = handRoot;
|
|
this.guide = guide;
|
|
LoadHand();
|
|
}
|
|
public void LoadHand()
|
|
{
|
|
GloveData gloveData = GContext.container.Resolve<PlayerFishData>().GetGloveData;
|
|
InitRodHandAsync(gloveData);
|
|
}
|
|
async void InitRodHandAsync(GloveData gloveData)
|
|
{
|
|
string path = gloveData.Fbx;
|
|
|
|
if (handAB != null)
|
|
{
|
|
Addressables.ReleaseInstance(handAB);
|
|
}
|
|
handAB = await Addressables.InstantiateAsync(gloveData.Fbx, handRoot).Task;
|
|
if (handAB != null)
|
|
{
|
|
HandController = handAB.GetComponent<HandController>();
|
|
if (crossbow != null)
|
|
{
|
|
HandController.SetHandTargets(crossbow.RightHandTargets, crossbow.LeftHandTargets, null);
|
|
}
|
|
}
|
|
}
|
|
public float CheckAngle(float value)
|
|
{
|
|
float angle = value - 180;
|
|
|
|
if (angle > 0)
|
|
return angle - 180;
|
|
|
|
return angle + 180;
|
|
}
|
|
|
|
//收线音效
|
|
Sound soundLine;
|
|
AudioClip lineAudio;
|
|
|
|
async void PlaySoundLine(string audioName)
|
|
{
|
|
StopSoundLine();
|
|
lineAudio = await Addressables.LoadAssetAsync<AudioClip>(audioName).Task;
|
|
if (lineAudio)
|
|
{
|
|
soundLine = GContext.container.Resolve<ISoundService>().GetNewFishingSound(lineAudio);
|
|
soundLine.audioSource.Play();
|
|
soundLine.audioSource.loop = true;
|
|
}
|
|
}
|
|
void StopSoundLine()
|
|
{
|
|
if (soundLine)
|
|
{
|
|
soundLine.audioSource.Stop();
|
|
soundLine.ReturnPool();
|
|
soundLine = null;
|
|
}
|
|
}
|
|
|
|
public void TriggerCrossbow(string value)
|
|
{
|
|
crossbow.animator.SetBool("Aim", value == "Aim");
|
|
crossbow.animator.SetBool("Back", value == "Back");
|
|
crossbow.animator.SetBool("Shoot", value == "Shoot");
|
|
|
|
//crossbow.animator.SetTrigger(value);
|
|
}
|
|
|
|
public async void Shoot(float[] FxScale, Dictionary<string, GameObject> fx_hunt_prefab, bool isRob, float cameraToFishDis, float shootTime, FishMovement fish)
|
|
{
|
|
crossbow.animator.SetTrigger("Shoot");
|
|
|
|
Vector3 targetPos = fish.targetPos;
|
|
manager.crossbowCamera.gameObject.SetActive(false);
|
|
Vector3 cameraposition = manager.crossbowCamera.transform.position;
|
|
float r = fish.AvoidRadius * cameraToFishDis;
|
|
|
|
float t = 1 - r / (targetPos - cameraposition).magnitude;
|
|
if (t < 0)
|
|
{
|
|
t = 0;
|
|
}
|
|
Vector3 newVector = Vector3.Lerp(cameraposition, targetPos, t);
|
|
|
|
GContext.Publish(new EventFishingSound("audio_huntingfish_shoot"));
|
|
crossbowArrow.gameObject.SetActive(true);
|
|
crossbow.fishingLineRenderer.enabled = true;
|
|
manager.cameraVirtual.gameObject.SetActive(false);
|
|
var cameraParent = manager.followArrowCamera.transform.parent;
|
|
//parent.position = manager.crossbowCamera.transform.position;
|
|
await Awaiters.NextFrame;
|
|
cameraParent.gameObject.SetActive(true);
|
|
manager.followArrowCamera.transform.localPosition = new Vector3(0.25f, 0.25f, -0.25f);
|
|
//cameraParent.position = manager.crossbowCamera.transform.position;
|
|
cameraParent.DOMove(newVector, shootTime).SetEase(Ease.Linear);
|
|
manager.followArrowCamera.LookAt = crossbowArrow.transform;
|
|
PlaySoundLine("audio_huntingfish_airflow");
|
|
transform.rotation = Quaternion.LookRotation(targetPos - transform.position);
|
|
crossbow.root.SetActive(false);
|
|
handRoot.gameObject.SetActive(false);
|
|
GameObject hunt_shoot_go = null;
|
|
if (fx_hunt_prefab.TryGetValue("fx_aquarium_hunt_shoot", out GameObject hunt_shoot))
|
|
{
|
|
hunt_shoot_go = Instantiate(hunt_shoot, crossbowArrow.transform);
|
|
}
|
|
crossbowArrow.transform.DOMove(targetPos, shootTime).SetEase(Ease.Linear);
|
|
await Awaiters.Seconds(shootTime);
|
|
manager.followArrowCamera.LookAt = null;
|
|
state = 1;
|
|
AddLinePos();
|
|
crossbowArrow.animator.SetTrigger("Shoot");
|
|
if (hunt_shoot_go != null)
|
|
{
|
|
Destroy(hunt_shoot_go);
|
|
}
|
|
|
|
|
|
if (fish.fish != null)
|
|
{
|
|
int q = fish.slotData.aquariumFishID - 1;
|
|
float fxScale = FxScale[q] / fish.transform.localScale.x;
|
|
GameObject hunt_fishhitbig_go = null;
|
|
GameObject hunt_fishhitsmall_go = null;
|
|
GameObject hunt_fishhurt_go = null;
|
|
|
|
Transform fishPos = isRob ? fish.fish.mouthPos : fish.fishPos;
|
|
|
|
if (fish.fish.Root && fx_hunt_prefab.TryGetValue("fx_aquarium_hunt_fishhitbig", out GameObject hunt_fishhitbig))
|
|
{
|
|
hunt_fishhitbig_go = Instantiate(hunt_fishhitbig, fish.fish.Root);
|
|
hunt_fishhitbig_go.transform.localScale = Vector3.one * fxScale;
|
|
hunt_fishhitbig_go.transform.rotation = Quaternion.identity;
|
|
}
|
|
if (fishPos && fx_hunt_prefab.TryGetValue("fx_aquarium_hunt_fishhitsmall", out GameObject hunt_fishhitsmall))
|
|
{
|
|
hunt_fishhitsmall_go = Instantiate(hunt_fishhitsmall, fishPos);
|
|
hunt_fishhitsmall_go.transform.localScale = Vector3.one * fxScale;
|
|
hunt_fishhitsmall_go.transform.rotation = Quaternion.identity;
|
|
}
|
|
if (fishPos && fx_hunt_prefab.TryGetValue("fx_aquarium_hunt_fishhurt", out GameObject hunt_fishhurt))
|
|
{
|
|
hunt_fishhurt_go = Instantiate(hunt_fishhurt, fishPos);
|
|
hunt_fishhurt_go.transform.localScale = Vector3.one * fxScale;
|
|
}
|
|
|
|
|
|
if (isRob)
|
|
{
|
|
GameObject hunt_capture_go = null;
|
|
if (fish.fish.Root && fx_hunt_prefab.TryGetValue("fx_aquarium_hunt_capture", out GameObject hunt_capture))
|
|
{
|
|
hunt_capture_go = Instantiate(hunt_capture, fish.fish.Root);
|
|
hunt_capture_go.transform.localScale = Vector3.one * fxScale;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GameObject hunt_escape_go = null;
|
|
if (fx_hunt_prefab.TryGetValue("fx_aquarium_hunt_escape", out GameObject hunt_escape))
|
|
{
|
|
hunt_escape_go = Instantiate(hunt_escape, fish.fish.Root);
|
|
hunt_escape_go.transform.localScale = Vector3.one * fxScale;
|
|
}
|
|
}
|
|
crossbowArrow.transform.parent = fishPos;
|
|
crossbowArrow.transform.localPosition = Vector3.zero;
|
|
if (isRob)
|
|
{
|
|
GContext.Publish(new EventFishingSound("audio_huntingfish_hitbig"));
|
|
}
|
|
else
|
|
{
|
|
GContext.Publish(new EventFishingSound("audio_huntingfish_hitsmall"));
|
|
}
|
|
}
|
|
StopSoundLine();
|
|
HideCrossbow(false);
|
|
crossbow.animator.SetTrigger("Capture");
|
|
}
|
|
Vector3 crossbowPos;
|
|
public void HideCrossbow(bool isHide)
|
|
{
|
|
guide = null;
|
|
if (isHide)
|
|
{
|
|
crossbowPos = crossbow.animator.transform.localPosition;
|
|
crossbow.animator.transform.localPosition = Vector3.back * 100;
|
|
}
|
|
else
|
|
{
|
|
crossbow.animator.transform.localPosition = crossbowPos;
|
|
}
|
|
//handRoot.localPosition = isHide ? Vector3.back * 100 : new Vector3(0, 1, -0.5f);
|
|
}
|
|
|
|
List<ParabolaHarmonicSimulation> vector3s = new List<ParabolaHarmonicSimulation>();
|
|
float lineChengeTime = 1;
|
|
|
|
|
|
public void Escape(float arrowEscapeTime)
|
|
{
|
|
GContext.Publish(new EventFishingSound("audio_huntingfish_escape"));
|
|
manager.followArrowCamera.LookAt = null;
|
|
HideCrossbow(false);
|
|
crossbowArrow.animator.SetTrigger("Escape");
|
|
crossbow.animator.SetTrigger("Escape");
|
|
crossbowArrow.transform.parent = crossbow.transform.parent;
|
|
crossbowArrow.transform.DOMoveY(-5, arrowEscapeTime).OnComplete(() =>
|
|
{
|
|
state = 2;
|
|
vector3s.Clear();
|
|
});
|
|
state = 1;
|
|
AddLinePos();
|
|
}
|
|
public void Target()
|
|
{
|
|
isFinish = true;
|
|
}
|
|
|
|
public float Capture(float fishToCameraDistance, float lineDrawMinTime, float cameraToFishDis, float lineDrawSpeed, FishMovement targetMovement)
|
|
{
|
|
manager.cameraVirtual.transform.DOKill();
|
|
manager.cameraVirtual.transform.localPosition = Vector3.zero;
|
|
manager.followArrowCamera.transform.position = manager.cameraVirtual.transform.position;
|
|
manager.followArrowCamera.transform.rotation = manager.cameraVirtual.transform.rotation;
|
|
manager.followArrowCamera.LookAt = targetMovement.transform;
|
|
crossbow.root.SetActive(true);
|
|
handRoot.gameObject.SetActive(true);
|
|
crossbowArrow.animator.SetTrigger("Capture");
|
|
PlaySoundLine("audio_huntingfish_capture");
|
|
|
|
state = 2;
|
|
vector3s.Clear();
|
|
|
|
Vector3 vector3 = targetMovement.targetPos;
|
|
Vector3 targetPos = crossbow.transform.position;
|
|
float r = targetMovement.AvoidRadius * cameraToFishDis;
|
|
float t = 1 - r / (targetPos - vector3).magnitude;
|
|
if (t < 0)
|
|
{
|
|
t = 0;
|
|
}
|
|
Vector3 newVector = Vector3.Lerp(vector3, targetPos, t);
|
|
newVector.z += fishToCameraDistance;
|
|
var captureTime = (crossbowArrow.transform.position - newVector).magnitude / lineDrawSpeed;
|
|
if (captureTime < lineDrawMinTime)
|
|
{
|
|
captureTime = lineDrawMinTime;
|
|
}
|
|
targetMovement.transform.DOMove(newVector, captureTime).SetEase(Ease.Linear)
|
|
.OnComplete(() => crossbow.animator.SetTrigger("CaptureEnd"));
|
|
return captureTime;
|
|
}
|
|
public void Captureed()
|
|
{
|
|
StopSoundLine();
|
|
crossbowArrow.transform.parent = crossbow.transform.parent;
|
|
crossbowArrow.transform.DOMoveY(-10, 3)
|
|
.OnComplete(() => crossbow.fishingLineRenderer.enabled = false);
|
|
}
|
|
async void AddLinePos()
|
|
{
|
|
float allTime = 1f;
|
|
float time = allTime;
|
|
float timeInterval = 0;
|
|
vector3s.Clear();
|
|
float elapsedTime = 0.02f;
|
|
|
|
while (time > 0)
|
|
{
|
|
elapsedTime = Time.deltaTime;
|
|
timeInterval += elapsedTime;
|
|
await Awaiters.Seconds(elapsedTime);
|
|
time -= elapsedTime;
|
|
ParabolaHarmonicSimulation parabolaHarmonicSimulation = new ParabolaHarmonicSimulation();
|
|
parabolaHarmonicSimulation.startPos = crossbowArrow.EndLine.position;
|
|
parabolaHarmonicSimulation.starTime = timeInterval;
|
|
parabolaHarmonicSimulation.curTime = timeInterval;
|
|
parabolaHarmonicSimulation.allTime = allTime;
|
|
vector3s.Add(parabolaHarmonicSimulation);
|
|
}
|
|
}
|
|
Vector3 GetCurPos(ParabolaHarmonicSimulation data, out float zeroTime)
|
|
{
|
|
data.curTime += Time.deltaTime;
|
|
float starTime = data.starTime;
|
|
float curTime = data.curTime - starTime;
|
|
|
|
//归0时间
|
|
zeroTime = curTime / data.allTime;
|
|
Vector3 vector3 = (crossbow.TopLine.position + crossbowArrow.EndLine.position) / 2;
|
|
if (zeroTime < 1)
|
|
{
|
|
Vector3 startPos = Vector3.Lerp(data.startPos, crossbowArrow.EndLine.position, zeroTime);
|
|
|
|
float time = curTime / lineChengeTime;
|
|
if (time < 1)
|
|
{
|
|
return Vector3.Lerp(startPos, vector3, time);
|
|
}
|
|
}
|
|
|
|
return vector3;
|
|
}
|
|
|
|
public float maxSegmentLength = 0.5f;
|
|
|
|
|
|
private List<Vector3> CalculateBezierPoint(List<Vector3> curPoints)
|
|
{
|
|
List<Vector3> points = new List<Vector3>();
|
|
points.Add(curPoints[0]);
|
|
for (int i = 1; i < curPoints.Count - 1; i++)
|
|
{
|
|
points.Add(CalculateBezierPoint(curPoints[i - 1], curPoints[i], curPoints[i + 1], 0.4f));
|
|
}
|
|
points.Add(curPoints[curPoints.Count - 1]);
|
|
return points;
|
|
}
|
|
//2次贝塞尔曲线
|
|
private Vector3 CalculateBezierPoint(Vector3 start, Vector3 midPoint, Vector3 end, float t)
|
|
{
|
|
Vector3 P0 = start;
|
|
Vector3 P1 = midPoint;
|
|
Vector3 P2 = end;
|
|
float u = 1 - t;
|
|
float tt = t * t;
|
|
float uu = u * u;
|
|
Vector3 p = uu * P0;
|
|
p += 2 * u * t * P1;
|
|
p += tt * P2;
|
|
return p;
|
|
}
|
|
|
|
|
|
|
|
private void LateUpdate()
|
|
{
|
|
if (crossbow != null && crossbowArrow.gameObject.activeSelf
|
|
&& crossbow.fishingLineRenderer != null
|
|
&& crossbow.fishingLineRenderer.enabled)
|
|
{
|
|
// 计算钓鱼线上的点
|
|
List<Vector3> linePoints = new List<Vector3>();
|
|
linePoints.Add(crossbow.EndLine.position);
|
|
for (int i = 0; i < crossbow.LineList.Count; i++)
|
|
{
|
|
linePoints.Add(crossbow.LineList[i].position);
|
|
}
|
|
linePoints.Add(crossbow.TopLine.position);
|
|
|
|
if (state == 1)
|
|
{
|
|
List<Vector3> newPoints = new List<Vector3>();
|
|
int count = vector3s.Count;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
Vector3 vector = GetCurPos(vector3s[i], out float zeroTime);
|
|
if (zeroTime < 1)
|
|
{
|
|
newPoints.Add(vector);
|
|
}
|
|
}
|
|
List<Vector3> refinedPoints = new List<Vector3>();
|
|
if (newPoints.Count > 0)
|
|
{
|
|
refinedPoints.Add(newPoints[0]);
|
|
for (int i = 1; i < newPoints.Count; i++)
|
|
{
|
|
Vector3 lastPoint = refinedPoints[refinedPoints.Count - 1];
|
|
Vector3 currentPoint = newPoints[i];
|
|
float distance = Vector3.Distance(lastPoint, currentPoint);
|
|
if (distance > maxSegmentLength)
|
|
{
|
|
int segments = Mathf.FloorToInt(distance / maxSegmentLength);
|
|
for (int j = 1; j <= segments; j++)
|
|
{
|
|
float t = j / (float)segments;
|
|
Vector3 intermediatePoint = Vector3.Lerp(lastPoint, currentPoint, t);
|
|
refinedPoints.Add(intermediatePoint);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
refinedPoints.Add(currentPoint);
|
|
}
|
|
}
|
|
}
|
|
|
|
refinedPoints.Add(crossbowArrow.EndLine.position);
|
|
for (int i = 0; i < crossbowArrow.LineList.Count; i++)
|
|
{
|
|
refinedPoints.Add(crossbowArrow.LineList[i].position);
|
|
}
|
|
linePoints.AddRange(CalculateBezierPoint(refinedPoints));
|
|
}
|
|
else
|
|
{
|
|
linePoints.Add(crossbowArrow.LineList[^1].position);
|
|
}
|
|
|
|
// 绘制钓鱼线
|
|
crossbow.fishingLineRenderer.positionCount = linePoints.Count;
|
|
crossbow.fishingLineRenderer.SetPositions(linePoints.ToArray());
|
|
}
|
|
//}
|
|
|
|
|
|
//private void LateUpdate()
|
|
//{
|
|
if (isFinish)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (Input.GetMouseButtonDown(0))
|
|
{
|
|
_curMousePos = Input.mousePosition;
|
|
_offsetEuler = Vector3.zero;
|
|
initialRotation = transform.rotation.eulerAngles;
|
|
initialRotation.x = CheckAngle(initialRotation.x);
|
|
initialRotation.y = CheckAngle(initialRotation.y);
|
|
targetRotation = transform.rotation;
|
|
}
|
|
else if (Input.GetMouseButton(0))
|
|
{
|
|
Vector3 ver = Input.mousePosition - _curMousePos;
|
|
if (ver.magnitude > 5)
|
|
{
|
|
_offsetEuler.x -= ver.y * dragCameraScale;
|
|
_offsetEuler.y += ver.x * dragCameraScale;
|
|
var targetEulerAngles = initialRotation + _offsetEuler;
|
|
|
|
//Debug.Log($"<color=#e94242> targetEulerAngles: {targetEulerAngles}</color>");
|
|
// Clamp the rotation angles
|
|
targetEulerAngles.x = Mathf.Clamp(targetEulerAngles.x, -cameraOffset.x, cameraOffset.x);
|
|
targetEulerAngles.y = Mathf.Clamp(targetEulerAngles.y, -cameraOffset.y, cameraOffset.y);
|
|
targetEulerAngles.z = 0;
|
|
_offsetEuler = targetEulerAngles - initialRotation;
|
|
//Debug.Log($"<color=#e94242> targetEulerAngles ===: {targetEulerAngles}</color>");
|
|
targetRotation = Quaternion.Euler(targetEulerAngles);
|
|
//transform.rotation = targetRotation;
|
|
_curMousePos = Input.mousePosition;
|
|
}
|
|
transform.rotation = Quaternion.Angle(targetRotation, transform.rotation) > 0.1f
|
|
? Quaternion.Lerp(transform.rotation, targetRotation, 0.2f)
|
|
: targetRotation;
|
|
}
|
|
else
|
|
{
|
|
|
|
if (guide != null)
|
|
{
|
|
//Vector3 targetDirection = target.transform.position - crossbowlowCamera.position;
|
|
//Vector3 currentDirection = crossbowlowCamera.forward;
|
|
//Quaternion rotationToTarget = Quaternion.FromToRotation(currentDirection, targetDirection);
|
|
//Quaternion rotation = rotationToTarget * transform.rotation;
|
|
Quaternion rotation = Quaternion.LookRotation(guide.transform.position - transform.position);
|
|
rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 2);
|
|
transform.eulerAngles = new Vector3(rotation.eulerAngles.x, rotation.eulerAngles.y, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|