0
点赞
收藏
分享

微信扫一扫

【Unity3D-Mirror多人坦克大战】角色的血量、子弹触发、子弹造成伤害(七)

兮城 2022-03-12 阅读 88

25、血量Canvas的制作

更改血条颜色

让滚动条右边的圆点消失(已经操作后的截图)

各组件配置如下:

在场景中,让名字置于血条前方

26、血量的显示

在Player.cs中更新代码:

using System;
using UnityEngine;
using UnityEngine.UI;
using Mirror;
public class Player : NetworkBehaviour
{
    ……
    public Text label;
    public Image hpImage;
    public Slider healthSlider;
    
    ……
    public override void OnStartClient()
    {
        Team team = GameManager.GetInstance().teams[teamIndex];
        for (int i = 0; i < renderers.Length; i++) // 遍历所有需要渲染的对象,即杆子和旗面
        {
            renderers[i].material = team.material;
        }
        // HP颜色的修改
        label.text = "Player";
        hpImage.color = team.color;
    }
    
    ……
}

将HUD这些canvas始终朝向摄像机

在LookAtCam.cs添加代码:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LookAtCam : MonoBehaviour
{
    private Transform camTransform;
    private Transform myTransform;
    private void Awake()
    {
        camTransform = Camera.main.transform;
        myTransform = this.transform;
    }
    private void Update()
    {
        myTransform.LookAt(myTransform.position + camTransform.rotation * Vector3.forward, camTransform.rotation * Vector3.up);
    }
}

测试

27、子弹功能的实现

由于子弹速度快,因此将碰撞检测换为连续,效果好点

在Bullet更新代码:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
public class Bullet : NetworkBehaviour
{
    ……
    public int damage = 3;
    
    ……
    [HideInInspector] [SyncVar] public GameObject owner;
    
    ……
    private void OnTriggerEnter(Collider other)
    {
        GameObject obj = other.gameObject;  // 获取子弹碰撞的对象
        Player player = obj.GetComponent<Player>(); // 获取该对象的player组件,如果无返回Null
        if (player != null) // 碰撞对象是坦克
        {
            if (player.gameObject == owner) return; // 是自己
            if (player.teamIndex == owner.GetComponent<Player>().teamIndex) return; // 是同类
            player.killedBy = owner;
        }
        if (!isServer) return;
        if(player) player.TankDamage(this); // 触发坦克少血机制
        
        Destroy(this.gameObject); // 子弹销毁
    }
}

在Player.cs中添加如下代码:

using System;
using UnityEngine;
using UnityEngine.UI;
using Mirror;
public class Player : NetworkBehaviour
{
    ……
    [HideInInspector] public int maxHealth;
    
    [HideInInspector] [SynVar] public GameObject killedBy; // 击杀对象
    
    ……
    [HideInInspector] [SyncVar(hook = nameof(OnHealthChange))] public int health = 10;
    
   ……
    
    private void Awake()
    {
        ……
        maxHealth = health;
    }

    ……
    
    ……
    
    [Command]
    void CmdShoot(short xPos, short zPos)
    {
        ……
        obj.GetComponent<Bullet>().owner = gameObject;
        ……
    }
    
    ……
    
    [Server]
    public void TankDamage(Bullet bullet)
    {
        health -= bullet.damage;
        if (health <= 10)
        {
            // 当前玩家死亡
        }
    }
    protected void OnHealthChange(int oldValue, int newValue)
    {
        health = newValue;
        healthSlider.value = (float)health / maxHealth;
    }
}

由于OnTriggerEnter的特殊性,可以看Unity基础篇。因为子弹和坦克都有刚体属性,而生成地没有刚体属性,所以子弹和坦克的Collider组件中,is trigger需要打勾, 此使坦克之间的碰撞也就失效了,而是执行 OnTriggerEnter函数的逻辑。

而子弹和生产地中有一个有刚体,所以无论如何都会触发OnTriggerEnter函数

测试

举报

相关推荐

0 条评论