Files
MinFt/Client/Assets/Scripts/Aquarium/CrossbowCameraMove.cs
Liubing\LB 3d8d4d18f3 first commit
先修复一下,错误的场景

删除不必要的钓场资产

修复into场景

update:更新meta文件,修复报错

update:修复资源

修复第一章节建造

修复建造第三章

update:删除多余内容

update:更新README.md

update:还原图标

update:更新README

update:更新配置
2026-04-28 02:17:22 +08:00

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);
}
}
}
}