当前位置: 首页 > news >正文

库车网站建设网站网址怎么写

库车网站建设,网站网址怎么写,wordpress表单设计,企业推广方案上期将基础的移动系统搭建完毕后就可以开始搭建更加复杂的系统部分了 前排提示#xff0c;由于一开始仅思考如何完成操作相关功能#xff0c;以至于到后面重构稍微有些困难#xff0c;继续写下去恐成屎山#xff0c;故在搭完射击和武器UI后不再继续泛化到敌人和敌人状态机…上期将基础的移动系统搭建完毕后就可以开始搭建更加复杂的系统部分了 前排提示由于一开始仅思考如何完成操作相关功能以至于到后面重构稍微有些困难继续写下去恐成屎山故在搭完射击和武器UI后不再继续泛化到敌人和敌人状态机 本次主要完成了 自由配置武器参数武器所需的所有参数都可进行调整 武器的追随准星 根据输入的武器槽位自动平滑的跟随指定武器的枪线换弹时也会有相应提示 武器的切换 不同武器根据数字键进行切换在UI和准星上也会有所体现 第一第三人称的切换 可以在第一第三人称间无缝切换 请看VCR Unity机甲2 文章目录 总览武器系统子弹第一第三人称转换UI 总览 类图结构 武器系统 武器使用状态机进行实现WeaponState继承自State内部持有Weapon的引用 Weapon是挂载在玩家身上的主要类一个武器对应一个Weapon手动输入索引标识其所属的武器槽位 public class Weapon : MonoBehaviour {public enum FireMode{Single,Brust,Auto}private Entity owner;public int weaponSelectIndex 0;public bool selected { get; private set; } false;[Header(武器性能)][SerializeField] private int maxAmmo 1; //最大弹匣弹药量[SerializeField] private int maxPrepareAmmo 16; //最大后备弹药量[SerializeField] private float shootingInterval 0.1f; //射击间隔[SerializeField] public float reloadTime 2; //换弹时间[Header(开火模式)][SerializeField] public FireMode fireMode FireMode.Single; //开火模式 [SerializeField] private int brustNum 3; //brust一次开火射出的子弹数[SerializeField] private float brustTime 1; //两次brust开火之间的间隔//[Header(武器状态参数)]private int curAmmo; //当前弹药量private int curPrepareAmmo; //当前后备弹药量private float shootingIntervalTimer 0; //射击间隔计时器private float brustTimeTimer 0; //brust射击间隔计时器private int brustCounter; //brust计数器[Header(发射物)][SerializeField] public Transform fireSocket; [SerializeField] private GameObject bulletPrefab; public float bulletVelocity 100; public float inertialVelocityMultipler 10; public bool constantSpeed false; //本来想做个委托外包出去想了想不如直接集成在类里得了[Header(特效效果)][SerializeField] private GameObject fireFX;private CinemachineImpulseSource impulseSource;public float cameraShakeMultipler 1f;[Header(音频)][SerializeField] private AudioClip fireSound;[SerializeField] private AudioClip reloadSound;[SerializeField] private float soundMultipler 1f;//玩家的输入对应的委托转发public UnityAction onFireStart, onFiring, onFireEnd, onReload;//换弹时的委托与UI通信使用public UnityAction onReloadStart, onReloadEnd;public UnityActionfloat onReloading;public UnityActionint, int onAmmoChanged;//是否选中public UnityActionbool onSelectChanged;//自己的状态机private StateMachine stateMachine new StateMachine();public WeaponIdleState idleState;public WeaponFireState fireState;public WeaponReloadState reloadState;private void Awake(){owner GetComponentEntity();impulseSource fireSocket.GetComponentCinemachineImpulseSource();if (weaponSelectIndex 1)selected true;//初始化数据curAmmo maxAmmo;curPrepareAmmo maxPrepareAmmo;brustTimeTimer brustTime;brustCounter brustNum;//状态初始化idleState new WeaponIdleState(stateMachine, this);fireState new WeaponFireState(stateMachine, this);reloadState new WeaponReloadState(stateMachine, this);//自身赋值到Controller方便其他组件引用PlayerController.Ins.weapons[weaponSelectIndex] this;}private void Start(){//玩家操作本Weaponowner.onFireStart () onFireStart?.Invoke();owner.onFireEnd () onFireEnd?.Invoke();owner.onReload () onReload?.Invoke();owner.onSelect (num) {selected num weaponSelectIndex;onSelectChanged?.Invoke(selected);};owner.onAllSelect () {selected true;onSelectChanged?.Invoke(selected);};//初始化状态机stateMachine.Init(idleState);}private void Update(){stateMachine.Update();if (shootingIntervalTimer 0)shootingIntervalTimer - Time.deltaTime;if (brustCounter 0 brustTimeTimer 0){brustTimeTimer - Time.deltaTime;if (brustTimeTimer 0)brustCounter brustNum;}if(owner.firing)onFiring?.Invoke();}public void ModifyAmmo(int amount){curAmmo amount;curAmmo Mathf.Clamp(curAmmo, 0, maxAmmo);onAmmoChanged?.Invoke(curAmmo, curPrepareAmmo);}public void Fire(){if (!CanFire())return;//发射投射物Bullet bullet Instantiate(bulletPrefab, fireSocket.position, fireSocket.rotation).GetComponentBullet();bullet.Init(bulletVelocity, constantSpeed, new Vector3(owner.velocity.x, 0, owner.velocity.z) * inertialVelocityMultipler, owner.flag);//数据更新ModifyAmmo(-1);shootingIntervalTimer shootingInterval;if (fireMode FireMode.Brust) //如果是Brust模式{brustCounter--;if (brustCounter 0)brustTimeTimer brustTime;}//播放枪口特效Instantiate(fireFX, fireSocket.position, fireSocket.rotation);//震动impulseSource.m_DefaultVelocity.x Random.Range(-1f, 1f) * cameraShakeMultipler;impulseSource.m_DefaultVelocity.y Random.Range(-1f, 1f) * cameraShakeMultipler;impulseSource.m_DefaultVelocity.z Random.Range(-1f, 1f) * cameraShakeMultipler;impulseSource.GenerateImpulse();//枪口音效AudioManager.PlayClipAtPoint(fireSound, fireSocket.position, soundMultipler);}public void Reload(){int needAmmo maxAmmo - curAmmo;curAmmo Mathf.Min(curPrepareAmmo, maxAmmo);curPrepareAmmo Mathf.Max(curPrepareAmmo - needAmmo, 0);onAmmoChanged?.Invoke(curAmmo, curPrepareAmmo);AudioManager.PlayClipAtPoint(reloadSound, owner.transform.position, soundMultipler);}public bool HaveAmmo() curAmmo 0;public bool HavePrepareAmmo() curPrepareAmmo 0;public bool CanFire(){if (!selected)return false;//没有子弹if (!HaveAmmo())return false;//没有结束冷却if (shootingIntervalTimer 0)return false;//如果在Brust模式//如果Counter小于等于0说明打完了否则不管//如果打完了并且还没过brust冷却那就不能打if (fireMode FireMode.Brust brustCounter 0 brustTimeTimer 0)return false;return true;}public bool CanBrust() brustCounter 0;public float GetReloadTime() reloadTime;public int GetCurAmmo() curAmmo;public int GetCurPrepareAmmo() curPrepareAmmo;public bool CanReload() curPrepareAmmo 0 curAmmo maxAmmo;public State GetCurState() stateMachine.curState; }武器的主要逻辑存在于状态机中 但是由于武器的开火分为连发单发爆发因此还需要做一些特殊的处理 以下是WeaponFireState 在使用爆发模式时即使玩家松开开火键也不能立即停止开火 public class WeaponFireState : WeaponCommonState {public bool readyEnd;public WeaponFireState(StateMachine stateMachine, Weapon weapon) : base(stateMachine, weapon){}public override void Enter(){base.Enter();weapon.onFireEnd OnFireEnd;FireOrReload();readyEnd false;}public override void Exit(){base.Exit();weapon.onFireEnd - OnFireEnd;}private void OnFireEnd(){if (weapon.fireMode ! Weapon.FireMode.Brust)stateMachine.ChangeState(weapon.idleState);readyEnd true;}public override void Update(){base.Update();//爆发模式if (weapon.fireMode Weapon.FireMode.Brust){if (weapon.CanBrust())FireOrReload();else if(readyEnd)stateMachine.ChangeState(weapon.idleState);}else if (weapon.fireMode Weapon.FireMode.Auto)FireOrReload();}private void FireOrReload(){if (weapon.HaveAmmo()){weapon.Fire();if (!weapon.HaveAmmo())stateMachine.ChangeState(weapon.reloadState);}elsestateMachine.ChangeState(weapon.reloadState);} }其他部分较为简短不特别描述 子弹 子弹同样使用一个通用的类进行配置 public class Bullet : MonoBehaviour {[Header(Physical)]private Rigidbody rb;private Vector3 lastPosition;[Header(Attribute)]//子弹所属派系可以设定是否开启友军伤害-1为中立派系public int flag -1;public float velocity 100;public bool constantSpeed false;public float lifeTime 6f;private float lifeTimer;public float gravityMultiper 1f;[Header(VFX)]public GameObject explosionPrefab;public GameObject trailPrefab;private void Awake(){rb GetComponentRigidbody();lastPosition transform.position;lifeTimer lifeTime;}public void Init(float velocity, bool constantSpeed, Vector3 inertialVelocity /*惯性力*/, int flag -1){this.velocity velocity;this.constantSpeed constantSpeed;rb.velocity transform.forward * velocity * Time.fixedDeltaTime / rb.mass;rb.AddForce(transform.forward * velocity inertialVelocity, ForceMode.Impulse);this.flag flag;}private void Update(){lifeTimer - Time.deltaTime;if (lifeTimer 0)OnCollisionEnter(null);}void FixedUpdate(){//防止错过刚体对即将经过的间隔做一个射线检测if (Physics.Raycast(lastPosition, rb.velocity.normalized, out RaycastHit hitInfo, rb.velocity.magnitude * Time.fixedDeltaTime)){transform.position hitInfo.point;rb.velocity Vector3.zero;return;}//持久动力if (constantSpeed)rb.AddForce(transform.forward * velocity);//调整旋转朝向transform.forward rb.velocity.normalized;//应用重力乘数rb.velocity new Vector3(0, 9.8f * (1 - gravityMultiper) * Time.fixedDeltaTime, 0);//记录位置lastPosition transform.position;}private void OnCollisionEnter(Collision collision){if(collision ! null collision.gameObject.TryGetComponent(out Entity entity)){if (entity.flag flag)return;}if (trailPrefab){trailPrefab.transform.parent null;var particleSystems trailPrefab.GetComponentsInChildrenParticleSystem();foreach (var particle in particleSystems){var main particle.main;main.loop false;}}Instantiate(explosionPrefab, transform.position, Quaternion.identity);Destroy(gameObject);}private void DelayTrail(){trailPrefab.SetActive(true);} }其内部包含初始惯性处理持续动力防止高速穿过物体的处理以及视觉和销毁时如果有拖尾的处理 第一第三人称转换 这一块比较简单直接使用Cinemachine自带的混合代码只需要控制两个虚拟相机的激活即可 public class PlayerCameraController : MonoBehaviour {//Third Person Camera[SerializeField] private CinemachineVirtualCamera thirdPersonCamera;private Cinemachine3rdPersonFollow thirdCameraBody;public float freeLookSide 0;public float freeLookDistance 20;float cameraSide;float cameraDistance;//First Peroson Camera[SerializeField] private CinemachineVirtualCamera firstPersonCamera;private Cinemachine3rdPersonFollow firstCameraBody;private Quaternion lastQuaternion;private void Awake(){thirdCameraBody thirdPersonCamera.GetCinemachineComponentCinemachine3rdPersonFollow();cameraSide thirdCameraBody.CameraSide;cameraDistance thirdCameraBody.CameraDistance;firstCameraBody firstPersonCamera.GetCinemachineComponentCinemachine3rdPersonFollow();}// Update is called once per framevoid Update(){HandleFreeLook();HandleSwitchView();}private void HandleFreeLook(){if (Input.GetKeyDown(KeyCode.C)){//控制器冻结lastQuaternion PlayerController.GetControllerRotation();PlayerController.SetPause(true);//第三人称参数thirdCameraBody.CameraSide freeLookSide;thirdCameraBody.CameraDistance freeLookDistance;//隐藏准星有视觉Bugforeach(var hair in UIManager.Ins.crossHairs){hair.gameObject.SetActive(false);}}if (Input.GetKeyUp(KeyCode.C)){//控制器恢复PlayerController.SetControllerRotation(lastQuaternion);PlayerController.SetPause(false);//第三人称参数thirdCameraBody.CameraSide cameraSide;thirdCameraBody.CameraDistance cameraDistance;//显示UIforeach (var hair in UIManager.Ins.crossHairs){hair.gameObject.SetActive(PlayerController.Ins.weapons[hair.weaponIndex].selected);}}}private void HandleSwitchView(){if (Input.GetKeyDown(KeyCode.V)){firstPersonCamera.gameObject.SetActive(!firstPersonCamera.gameObject.activeSelf);thirdPersonCamera.gameObject.SetActive(!thirdPersonCamera.gameObject.activeSelf);}} }UI 比较重要的地方是丝滑的UI跟随以及实时的武器栏 后者只需要在制作时留意委托就可以很方便的调用前者则需要一些不同空间的变换知识 准星的跟随部分 一开始我在Canvas中选择的渲染模式是覆盖后来发现在覆盖的模式下不能添加自发光导致UI较暗于是调整为了摄像机空间但调整后导致原本跟踪正确的准星又不再正确下面是解决办法 public class CrossHairUI : MonoBehaviour {//自身private RectTransform rect, parent;[SerializeField] private GameObject aimHair, reloadHair;[SerializeField] private TextMeshPro reloadTxt;//武器public int weaponIndex 0;private Weapon weapon;private Transform fireSocket;public float lerpMultipler 0.1f;void Start(){rect GetComponentRectTransform();parent rect.parent.GetComponentRectTransform();weapon PlayerController.Ins.weapons[weaponIndex];fireSocket weapon.fireSocket;weapon.onReloadStart OnReloadStart;weapon.onReloading OnReloading;weapon.onReloadEnd OnReloadEnd;weapon.onSelectChanged (selected) {gameObject.SetActive(selected);};gameObject.SetActive(weapon.selected);}void Update(){if (Physics.SphereCast(fireSocket.position, .5f, fireSocket.forward, out RaycastHit hitInfo, 1000)){if(RectTransformUtility.ScreenPointToLocalPointInRectangle(parent, RectTransformUtility.WorldToScreenPoint(Camera.main, hitInfo.point), Camera.main, out Vector2 localPoint)){rect.localPosition Vector2.Lerp(rect.localPosition, localPoint, lerpMultipler);}}else{Vector3 point fireSocket.position fireSocket.forward * 3000;if (RectTransformUtility.ScreenPointToLocalPointInRectangle(parent, RectTransformUtility.WorldToScreenPoint(Camera.main, point), Camera.main, out Vector2 localPoint)){rect.localPosition Vector2.Lerp(rect.localPosition, localPoint, lerpMultipler);}}}private void OnReloadStart(){aimHair.SetActive(false);reloadHair.SetActive(true);}private void OnReloading(float remainTime){reloadTxt.SetText(remainTime.ToString(0.00));}private void OnReloadEnd(){aimHair.SetActive(true);reloadHair.SetActive(false);} }在Update中首先SphereCast来获取击中的点再将其WorldToScreenPoint变换到屏幕空间如果是覆盖的渲染模式此时已经结束了但由于是摄像机模式因此需要再多一个变换即ScreenPointToLocalPointInRectangle将其变换到面板上的相对位置。之后使用插值即可实现丝滑的跟踪准
http://www.zqtcl.cn/news/80089/

相关文章:

  • 高端品牌网站建设方案如何开发wordpress主题
  • 网站备案更换内江建网站
  • 广西网站推广优化自助业务网站系统
  • 汕头如何建设网站设计wordpress单页调用标题
  • 网站的组成东莞东城网站建设
  • 沈阳网站建设优秀公司杭州正规企业网站建设
  • 贵州建网站报价linux部署wordpress
  • 建设银行网站不能登录密码错误网站开发合同编号如何编写
  • 网站建设重点htp免费域名注册网站
  • 软件优化网站爱范儿 wordpress 主题
  • 我国有哪些企业网站网站后台和移动开发
  • 六安市网站制作华为荣耀手机最新款
  • 深圳做网站便宜app怎么查网站备案
  • 怎么做触屏版网站一键建站模板
  • 学做美食的网站网站官网建设
  • 珠海网站建设费用医疗网站建设哪家好
  • 二手书交易网站策划书2017设计工作室做网站
  • 网站建设策划包括哪些内容诚信网站建设
  • 做网站推广邢台wordpress写代码
  • 支付宝网站开发流程安徽省水利厅j建设网站
  • 北京海淀网站建设临沂网站建设培训学校
  • 网站后台怎么添加栏目纳雍网站建设公司
  • 河南省住房与城乡建设厅网站首页wordpress 移植
  • 合肥设计网站睢宁做网站公司
  • 网站设计规划说明书做游戏网站需要多少钱
  • 手机网站自助建站系统想建设一个网站自己接一些小活
  • 医院网站建设方案免费无限建站系统
  • 那个网站做网编好软件开发中需要哪些可行性分析
  • sae 企业网站大连模版网站
  • 北京网站建设需要多少钱wordpress实用功能