0


unity,射手游戏

文章目录


介绍

3d游戏。
玩家自由移动。
持枪发射子弹。
随机生成的坦克追踪玩家。
坦克发射子弹攻击玩家。
hp归零死亡

在这里插入图片描述


一,制作玩家具体函数脚本PlayerCharacter

设置float:移动速度、转动速度、子弹发射速度、现在生命值、最大生命值、两次攻击时间间隔。

设置bool:是否正在攻击、是否死亡

其他组件:角色控制器、生命值滑动条、最大生命值颜色(绿色)、最小生命值颜色(红色)、音频源、动画器、粒子系统

publicfloat speed;publicfloat turnSpeed;publicfloat health;publicfloat attackTime;publicfloat health;float healthMax;bool isAlive;bool attacking =false;CharacterController cc;Animator animator;publicSlider healthSlider;publicImage healthFillImage;publicColor healthColorFull = Color.green;publicColor HealthColorNull = Color.red;publicParticleSystem explosionParticles;publicRigidbody shell;publicTransform muzzle;
start方法,获取动画器、角色控制器、生命值最大化、bool设置活着、更新血条滑块、死亡爆炸效果设置为不可见。
animator =GetComponentInChildren<Animator>();
        cc =GetComponent<CharacterController>();
        healthMax = health;
        isAlive =true;RefreshHealthHUD();
        explosionParticles.gameObject.SetActive(false);
玩家被攻击,生命值减少amount,更新血条,如果生命值小于零,死亡
publicvoidTakeDamage(float amount){
        health -= amount;RefreshHealthHUD();if(health <=0f&& isAlive){Death();}}
更新血条,滑块的value值更新一次,血条由100%的绿色,变成百分之(health / healthMax)的绿色。
publicvoidRefreshHealthHUD(){
        healthSlider.value= health;
        healthFillImage.color = Color.Lerp(HealthColorNull, healthColorFull, health / healthMax);}
死亡,角色是否活着设置为否,播放粒子特效,当粒子系统的持续时间结束后,粒子系统对象就会被销毁,设置玩家为不可见。
publicvoidDeath(){
        isAlive =false;
        explosionParticles.transform.parent =null;
        explosionParticles.gameObject.SetActive(true);ParticleSystem.MainModule mainModule = explosionParticles.main;Destroy(explosionParticles.gameObject, mainModule.duration);
        gameObject.SetActive(false);}
角色移动,传入一个向量值,必须在活着、没有攻击才能移动。
角色控制器使用simplemove函数,移动的时候,控制“speed”动画,开始播放
publicvoidMove(Vector3 v){if(!isAlive)return;if(attacking)return;Vector3 movement = v * speed;
        cc.SimpleMove(movement);if(animator){
            animator.SetFloat("Speed", cc.velocity.magnitude);}}
人物旋转函数,玩家往哪里跑,角色人物头就转向哪里
设置目标位置、当前位置
四元数转向
使用球面插值,平滑转动
publicvoidRotate(Vector3 lookDir){var targetPos = transform.position + lookDir;var characterPos = transform.position;//去除Y轴影响
        characterPos.y =0;
        targetPos.y =0;//角色面朝目标的向量Vector3 faceToDir = targetPos - characterPos;//角色面朝目标方向的四元数Quaternion faceToQuat = Quaternion.LookRotation(faceToDir);//球面插值Quaternion slerp = Quaternion.Slerp(transform.rotation, faceToQuat, turnSpeed * Time.deltaTime);

        transform.rotation = slerp;}
开火脚本
必须活着、不正在开火才能调用
生成一个子弹刚体,玩家自身位置,枪口方向转向,设置发射速度
播放开火音效
动画器播放开火动作
延迟attachtime发射一次,设置发射频率
publicvoidFire(){if(!isAlive)return;if(attacking)return;Rigidbody shellInstance =Instantiate(shell, muzzle.position, muzzle.rotation)asRigidbody;
        shellInstance.velocity = launchForce * muzzle.forward;
        shootAudioSource.Play();if(animator){
            animator.SetTrigger("Attack");}

        attacking =true;Invoke("RefreshAttack", attackTime);}
发射时间间隔脚本,时间未到,不能发射
voidRefreshAttack(){
        attacking =false;}

三、 制作玩家控制脚本 PlayerController,调用上面的函数方法

start方法获取角色控制器
void Start (){
        character =GetComponent<PlayerCharacter>();}
固定帧数刷新。
鼠标左键调用点击开火函数
键盘wsad控制人物移动
人物移动的方向和人物转向的方向保持一致
voidFixedUpdate(){if(Input.GetButtonDown("Fire1")){
            character.Fire();}var h = Input.GetAxis("Horizontal");var v = Input.GetAxis("Vertical");
        character.Move(newVector3(h,0, v));var lookDir = Vector3.forward * v + Vector3.right * h;if(lookDir.magnitude !=0){
            character.Rotate(lookDir);}}

四、 制作子弹脚本 shell

设置float参数:子弹生存时间、爆炸半径、爆炸力量、最大伤害

设置bool参数:子弹是否正在旋转

设置其他:音频源、层级、粒子系统
publicfloat lifeTimeMax =2f;publicAudioSource explosionAudioSource;publicParticleSystem explosionParticles;publicfloat explosionRadius;publicfloat explosionForce =1000f;publicfloat damageMax =100f;publicLayerMask damageMask;publicbool isRotate =false;

start方法,添加扭矩,模拟子弹旋转

void Start (){if(isRotate){GetComponent<Rigidbody>().AddTorque(transform.right *1000);}}
触发器碰撞检测
在当前游戏对象的位置上创建一个球形的检测区域,并检测该区域内是否有与指定层级(damageMask)匹配的碰撞器(colliders)。如果有,则返回一个碰撞器数组(Collider[]),其中包含了所有与当前游戏对象在指定半径(explosionRadius)内发生碰撞的游戏对象的碰撞器。通常用于实现爆炸伤害、碰撞检测等功能。    
遍历数组,计算伤害
播放粒子特效
privatevoidOnTriggerEnter(Collider other){Collider[] colliders = Physics.OverlapSphere(transform.position, explosionRadius, damageMask);foreach(var collider in colliders){var targetCharacter = collider.GetComponent<PlayerCharacter>();if(targetCharacter){
                targetCharacter.TakeDamage(CalculateDamage(collider.transform.position));}}
        explosionParticles.transform.parent =null;
         explosionAudioSource.Play();
        explosionParticles.Play();ParticleSystem.MainModule mainModule = explosionParticles.main;// Destroy(explosionParticles.gameObject, mainModule.duration);Destroy(gameObject);}
计算伤害,传入向量值
距离越小,伤害比例越大
设置最低伤害Mathf.Max()函数,最低伤害为2
floatCalculateDamage(Vector3 targetPosition){var distance =(targetPosition - transform.position).magnitude;//距离越小,伤害比例越大var damageModify =(explosionRadius - distance)/ explosionRadius;var damage = damageModify * damageMax;return Mathf.Max(2f, damage);}

五、 给玩家挂载脚本

设置参数,添加预制体子弹
在这里插入图片描述


六、 制作坦克脚本

设置导航网格、play对象
NavMeshAgent agent;PlayerCharacter character;Transform targetTrans;
start函数,获取玩家实例,
导航网格寻找玩家
延迟1秒后,每隔三秒发射一次子弹
void Start (){
        character =GetComponent<PlayerCharacter>();
        agent =GetComponent<NavMeshAgent>();

        targetTrans = GameObject.FindGameObjectWithTag("Player").transform;InvokeRepeating("FireControl",1,3);}
开火控制函数,调用共同使用的fire()方法。
voidFireControl(){
        character.Fire();}
update()函数,不断追踪玩家的位置,
转向玩家
void Update (){
        agent.destination = targetTrans.position;
        transform.LookAt(targetTrans);}

七、 给坦克添加组件

在这里插入图片描述


八、 开始游戏,播放动画

在这里插入图片描述

人物移动、坦克移动

在这里插入图片描述


九、 下载

https://pan.baidu.com/s/1RVemZY_THhhpD0v_IcQS2w

提取码:tdq9

+



本文转载自: https://blog.csdn.net/qq_20179331/article/details/130048969
版权归原作者 忽然602 所有, 如有侵权,请联系我们删除。

“unity,射手游戏”的评论:

还没有评论