Unity 钓鱼玩法的初步实现

您所在的位置:网站首页 原神基于unity Unity 钓鱼玩法的初步实现

Unity 钓鱼玩法的初步实现

2023-08-17 20:39| 来源: 网络整理| 查看: 265

效果

https://www.bilibili.com/video/BV13r4y1q7vE

实现思路

钓鱼的核心玩法是:

甩钩,等待鱼咬钩后,再给予鱼线适当的力度把鱼给拉上来。

鱼的拉力用随机值模拟。

人的拉力则用按键来控制。如果不增加拉力,人对鱼竿的拉力会随着时间减小至0。按下L键时,就会在原拉力的基础上再给鱼竿增加一定的拉力。

如果人与鱼的拉力受力平衡时,可以看作是合适的拉力。

在合适的拉力范围内,积累一定的时间,即可将鱼钓上来。

鱼竿脚本

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; public class Fishing : MonoBehaviour { /*--------------核心玩法----------------*/ public float lineTension = 0.5f; public float deviation = 0.1f; //偏差范围 public float resultantForce = 0; //合力 public float fishForce = 0; public float fishingRodForce = 0; public float fishingRodForceDeclinePerSec = 0.15f; //人的拉力每秒减少量 public float targetAccumulationTime = 5f; public float currentAccumulationTime = 0; public float accumulationRate = 0; //积累进度 /*--------------UI----------------*/ public GameObject canvas; public GameObject TensionPanel; public Image curTensionBar; //力度条 public Image acRateBar; //时间条 public Text status; //状态提示文本 public FishingStatus fishingStatus = FishingStatus.notAtFishing; public enum FishingStatus { wait, hit, caught, notAtFishing, } void Update() { AdjustLength(); if (fishingStatus == FishingStatus.caught) MoveWithHook(); if (fishingStatus == FishingStatus.hit) { AdjustTension(); } } void AdjustTension() { fishForce = Mathf.Lerp(fishForce, Random.Range(0, 1f), 0.2f); float fishingRodForceIncrease = (Input.GetKeyDown(KeyCode.L) ? 1 : 0) * 0.05f; float fishingRodForceDecrease = fishingRodForce - fishingRodForceDeclinePerSec * Time.deltaTime >= 0 ? fishingRodForceDeclinePerSec * Time.deltaTime : 0; fishingRodForce = fishingRodForce + fishingRodForceIncrease - fishingRodForceDecrease; fishingRodForce = Mathf.Clamp(fishingRodForce, 0, 1f); resultantForce = fishingRodForce - fishForce; lineTension = resultantForce + 0.5f; lineTension = Mathf.Clamp(lineTension, 0, 1f); if (lineTension = (0.5f - deviation)) { currentAccumulationTime += Time.deltaTime; } else { currentAccumulationTime -= Time.deltaTime; } currentAccumulationTime = Mathf.Clamp(currentAccumulationTime, 0, targetAccumulationTime); accumulationRate = currentAccumulationTime / targetAccumulationTime; curTensionBar.fillAmount = lineTension; acRateBar.fillAmount = accumulationRate; if(accumulationRate == 1) { OnCaught(); } } void MoveWithHook() { if (fish) fish.transform.position = transform.position; } IEnumerator CloseFishingUI() //延迟关闭UI { float timer = 0; while (true) { timer += Time.deltaTime; yield return null; if (timer > 5) { canvas.gameObject.SetActive(false); StopCoroutine("CloseFishingUI"); } } } private GameObject fish; private void OnTriggerEnter(Collider other) //将钩子作为触发器,则必须将该脚本挂在钩子上 { if (other.gameObject.name == "fish") { fish = other.gameObject; if(fish.GetComponent().hookStatus == Fish.HookStatus.focusOnHook) OnEatHook(); } } public GameObject fishingLine; public float fishingLineLength = 1; void AdjustLength() { if(Input.GetMouseButton(0)) fishingLineLength += Input.GetAxis("Mouse ScrollWheel"); fishingLine.transform.localScale = new Vector3(fishingLine.transform.localScale.x, fishingLine.transform.localScale.y, Mathf.Clamp(fishingLineLength, 1f,7f)); } public void OnUnhook() { status.text = "鱼脱钩了"; fishingStatus = FishingStatus.notAtFishing; TensionPanel.gameObject.SetActive(false); StartCoroutine("CloseFishingUI"); } public void OnCaught() { status.text = "钓上来了"; fishingStatus = FishingStatus.caught; fish.GetComponent().hookStatus = Fish.HookStatus.caught; TensionPanel.gameObject.SetActive(false); StartCoroutine("CloseFishingUI"); } public void OnEatHook() { status.text = "鱼吃钩了.."; fishingStatus = FishingStatus.hit; canvas.gameObject.SetActive(true); TensionPanel.gameObject.SetActive(true); } public void OnSwingHook() { status.text = "静静等待"; fishingStatus = FishingStatus.wait; canvas.gameObject.SetActive(true); TensionPanel.gameObject.SetActive(false); StartCoroutine("SwingHookAnimation"); } public GameObject fishingRod; IEnumerator SwingHookAnimation() //延迟甩钩动画 { float timer = 0; while(true) { timer += Time.deltaTime; yield return null; if(timer >= 0.5f && timer = 1f && timer 1.5f) StopCoroutine("SwingHookAnimation"); } } }

鱼的脚本

using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; public class Fish : MonoBehaviour { public GameObject hook; //鱼钩 public float eatHookDistance = 10f; //吃钩距离 public HookStatus hookStatus = HookStatus.normal; public enum HookStatus { normal, focusOnHook, caught, } void Update() { if (Input.GetKeyDown(KeyCode.K) && (hook.GetComponent().fishingStatus == Fishing.FishingStatus.notAtFishing || hook.GetComponent().fishingStatus == Fishing.FishingStatus.wait)) { hook.GetComponent().OnSwingHook(); StartCoroutine("FindFood"); } if(hookStatus == HookStatus.focusOnHook) ChaseHook(); } IEnumerator FindFood() //延迟吃钩 { float timer = 0; while (true) { timer += Time.deltaTime; yield return null; if (timer > 10) { //注意到钩子 hookStatus = HookStatus.focusOnHook; GetComponent().DOPause(); fish_y = transform.position.y; lastHookPosition = new Vector3(hook.transform.position.x, fish_y, hook.transform.position.z); StopCoroutine("FindFood"); } } } public Vector3 lastHookPosition; private float fish_y; //鱼受到浮力作用,纵坐标是时刻变化的 void ChaseHook() { //随意移动鱼钩位置,鱼跑了 if (lastHookPosition != new Vector3(hook.transform.position.x, fish_y, hook.transform.position.z) && lastHookPosition != Vector3.zero) { hookStatus = HookStatus.normal; lastHookPosition = Vector3.zero; GetComponent().DORestart(); //改变了位置之后不可继续播放,只能重新播放 hook.GetComponent().OnUnhook(); return; } if (Vector3.Distance(hook.transform.position, transform.position) < eatHookDistance) //向钩子移动 { if (Vector3.Distance(hook.transform.position, transform.position) > 0.5f) transform.position = Vector3.Lerp(transform.position, lastHookPosition,0.05f); transform.LookAt(hook.transform); } } }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3