移动手机网站开发,湖南人文科技学院全国排名,青州做网站电话,商务网站建设教程前言#xff1a;实现了武器的基本发射功能#xff0c;但是我们弹夹数量是有限#xff0c;之前并没有做装弹和弹夹显示的功能。本篇实现装弹和弹夹显示。 装弹和弹夹UI显示 装弹目标思路和实现 弹夹UI显示目标弹夹UI的思路和实现UI代码的思路和实现 武器控制的完整代码效果补…前言实现了武器的基本发射功能但是我们弹夹数量是有限之前并没有做装弹和弹夹显示的功能。本篇实现装弹和弹夹显示。 装弹和弹夹UI显示 装弹目标思路和实现 弹夹UI显示目标弹夹UI的思路和实现UI代码的思路和实现 武器控制的完整代码效果补充知识锚点 装弹
目标
Unity官方的项目中如果不是满弹夹的情况子弹的数量会随时间自动增加。
思路和实现
如果子弹没有满且在没有开枪的情况下子弹会自动装填。
由于子弹的自动装填是随着时间慢慢增加的可以通过协程来实现。
public float reloadBulletTime 2F;// 每次装弹的时间
public int reloadBulletNum 10;// 每次装弹的数量
IEnumerator ReloadBullet()
{while (!isFirecurrentBulletNumbulletNum)// 达到弹夹容量协程自己会停止运行{yield return new WaitForSeconds(reloadBulletTime);currentBulletNum (reloadBulletNumcurrentBulletNum)bulletNum?bulletNum:(reloadBulletNum currentBulletNum);// 判断一下会不会超过弹夹容量}
}当子弹左键按下的时候就表示要开枪这时候就应该停止装弹协程。 当子弹左键松开的时候就表示停止开枪这时候就应该开启装弹协程。
private void OpenFire()
{if (Input.GetMouseButtonDown(0)){StopCoroutine(ReloadBullet);isFire true;StartCoroutine(Shoot);}if (Input.GetMouseButtonUp(0)){isFire false;StopCoroutine(Shoot);StartCoroutine(ReloadBullet);}
}弹夹UI显示
目标
子弹数量发生变化的时候弹夹会有一个UI进度条提醒当前子弹的情况。
弹夹UI的思路和实现
UI毫无疑问得在Canvas上进行。
在之前显示做准星的Canvas上右键UI-Slider添加一个滑动条。 默认的Slider中三个部分分别对应界面内容如下Backgroud是滑动条底色Fill Area是滑动区域Handle Slider Area是滑动区域末尾小圆球。 其中Handle Slider Area小圆球我们可以删掉因为我们并不用。 把Fill Area中的Fill拖到和Backgroud平级并调整strech伸展左右铺满Fill Area作用不大可以删掉只是更好约束了Fill的strech。 接下来调整颜色和样式给Backgroud和Fill选择方形的背景图片TEX_Black和TEX_White。下面演示了是如何找到素材和切换背景图片。 然后修改Fill的颜色模仿Unity官方案例的蓝色然后调整Slider大小。 位置为常在的右下角这个Slider直接拖动到右下角是没有用的可以通过锚点来常驻右下角。锚点调到右下角后再拖动到合适位置。这样屏幕无论怎么样变化Slider位置都是相对右下角进行变化的。 添加弹夹的UISlider下面右键新增UI-Image然后切换Source Image为武器的图标。切换图片后可以Set Native Size可将图像框的尺寸设置为纹理的原始像素大小不会变形太厉害。 调整武器的图标大小到合适。
UI代码的思路和实现
代码控制Slider先在代码中添加Slider组件添加后Unity把组件拖过来就行了。
public Slider bulletSlider;// 弹夹Slider UI在Start函数中初始化Slider最大值和当前值。
void Start()
{if (bulletSlider){bulletSlider.maxValue bulletNum;bulletSlider.value currentBulletNum;}
}在子弹数量会发生变化的地方进行Slider更新会发生变化的地方只有发射子弹Shoot和装弹ReloadBullet两个协程中。
IEnumerator Shoot()
{while (isFire){if (currentBulletNum 0){GameObject newBullet bulletPool.Get();currentBulletNum--;// 更新弹夹数量if (bulletSlider)bulletSlider.value currentBulletNum;}yield return new WaitForSeconds(shootInterval);}
}
IEnumerator ReloadBullet()
{while (!isFirecurrentBulletNumbulletNum){yield return new WaitForSeconds(reloadBulletTime);currentBulletNum (reloadBulletNumcurrentBulletNum)bulletNum?bulletNum:(reloadBulletNum currentBulletNum);// 更新弹夹数量if (bulletSlider)bulletSlider.value currentBulletNum;}
}武器控制的完整代码
这次主要修改的WeaponController的代码下面是修改后WeaponController的完整代码。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;
using UnityEngine.UI;public class WeaponController : MonoBehaviour
{[Header(武器数值)]public Vector3 defaultPosition new Vector3(0.4F, -0.6F, 1.15F);// 默认位置public Vector3 centerPosition new Vector3(0F, -0.6F, 0.807F);// 中心位置public float positionLerpRatio 0.5f;// 线性插值参数[Header(子弹数值)]public Transform shootPoint;// 子弹发射位置public GameObject bullet;// 子弹预制体public float shootInterval 1;// 子弹间隔时间private bool isFire;// 发射状态public int bulletNum 100;// 弹夹public int currentBulletNum;// 当前子弹的数量public float reloadBulletTime 2F;// 每次装弹的时间public int reloadBulletNum 10;// 每次装弹的数量public Slider bulletSlider;// 弹夹Slider UIprivate ObjectPoolGameObject bulletPool;// 子弹对象池private void Awake(){currentBulletNum bulletNum;bulletPool new ObjectPoolGameObject(CreateBullet,BulletOnGet, BulletOnRelease, BulletOnDestory,true,10,bulletNum);}GameObject CreateBullet(){GameObject obj Instantiate(bullet, shootPoint);obj.GetComponentBulletController().bulletPool bulletPool;return obj;}void BulletOnGet(GameObject obj){obj.GetComponentBulletController().BulletReset();obj.gameObject.SetActive(true);}void BulletOnRelease(GameObject obj){obj.gameObject.SetActive(false);}void BulletOnDestory(GameObject obj){Destroy(obj);}void Start(){// 弹夹UI初始化if (bulletSlider){bulletSlider.maxValue bulletNum;bulletSlider.value currentBulletNum;}}void Update(){ChangePosition();OpenFire();}private void OpenFire(){if (Input.GetMouseButtonDown(0)){StopCoroutine(ReloadBullet);isFire true;StartCoroutine(Shoot);}if (Input.GetMouseButtonUp(0)){isFire false;StopCoroutine(Shoot);StartCoroutine(ReloadBullet);}}IEnumerator Shoot(){while (isFire){if (currentBulletNum 0){//GameObject newBullet Instantiate(bullet, shootPoint);GameObject newBullet bulletPool.Get();currentBulletNum--;// 弹夹UI更新if (bulletSlider)bulletSlider.value currentBulletNum;}yield return new WaitForSeconds(shootInterval);}}private void ChangePosition(){// 按下左键if (Input.GetMouseButtonDown(1)){StopCoroutine(ToDefault);StartCoroutine(ToCenter);}// 松开左键if (Input.GetMouseButtonUp(1)){StopCoroutine(ToCenter);StartCoroutine(ToDefault);}}IEnumerator ToCenter() {while (transform.localPosition!centerPosition){transform.localPosition Vector3.Lerp(transform.localPosition, centerPosition, positionLerpRatio);yield return null;// 等待一帧}}IEnumerator ToDefault(){while (transform.localPosition ! defaultPosition){transform.localPosition Vector3.Lerp(transform.localPosition, defaultPosition, positionLerpRatio);yield return null;// 等待一帧}}IEnumerator ReloadBullet(){while (!isFirecurrentBulletNumbulletNum){yield return new WaitForSeconds(reloadBulletTime);currentBulletNum (reloadBulletNumcurrentBulletNum)bulletNum?bulletNum:(reloadBulletNum currentBulletNum);// 弹夹UI更新if (bulletSlider)bulletSlider.value currentBulletNum;}}
}
效果 补充知识
锚点
Canvas下创建UI会自带四个△为锚点如下图。 锚点可以分开可以构成矩形。 Unity中UI属性可以设置锚点红色框部分是锚点在一起黄色框部分是锚点分开。这两个属性在本篇弹夹显示的UI中都用到的了。 锚点在一起的时候图片的大小不会随着父对象的大小改变而改变但是图片定位是相对锚点进行定位的。例如本文实现弹夹显示在右下角的时候锚点就被设置在了右下角。
锚点分开的时候用作与拉伸锚点的位置会随着父物体的大小进行变动。例如本文实现弹夹显示条调整父物体Slider的大小时候里面的显示条也会跟着拉伸。