首页 > 解决方案 > 当玩家射击时,它正在失去生命

问题描述

我正在制作多人游戏 2d,当我的玩家射击时(枪也有对撞机),这会影响他的生活,我不知道为什么。可能是因为当目标“受伤”时有 RPCtarget.all 但我不知道改变什么只是为了影响游戏中的其他玩家,而不是我的。我可以用什么来代替一切?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using Photon.Pun;
using Photon.Realtime;
using Photon;
using UnityEngine.UI;


public class Character : MonoBehaviourPun,IPunObservable
{

    Rigidbody2D rb;
    float dirX;
    
    [SerializeField]
    float moveSpeed = 5f, jumpForce = 400f, bulletSpeed = 500f;

    [SerializeField] private float health = 100;
    [SerializeField] private Slider slider;
    [SerializeField] private Gradient gradient;
    [SerializeField] private Image fill;
    public Rigidbody2D bulletPrefabs;
    Vector3 localScale;
    public DeathsCount myCounts;
    public Transform barrel;
    public Rigidbody2D bullet;

 

    // Use this for initialization
    void Start()
    {
        localScale = transform.localScale;
        rb = GetComponent<Rigidbody2D>();
        if (photonView.IsMine)
        {
             myCounts = FindObjectOfType<DeathsCount>();
        }
        else
        {

        }
    }
    

    public float Health
    {
        get { return health; }
        set
        {
            health = value;
            slider.value = health;
           // fill.color = gradient.Evaluate(slider.normalizedValue);
        }
    }

    private void OnTriggerEnter2D(Collider2D col)
    {
        if (col.gameObject.CompareTag("Hurt"))
        {
            if (photonView.IsMine)
            {
                photonView.RPC("Damage", RpcTarget.All);
            }
        }
        if (col.gameObject.tag == "PowerUp")
        {
            if (photonView.IsMine)
            {
                var powerup = col.GetComponent<PowerUp>();
                powerup.Pickup(this);
            }
            else
            {

            }

        }
        if (col.gameObject.CompareTag("Bullet"))
        {
            if (photonView.IsMine)
            {
                photonView.RPC("Damage", RpcTarget.All);
                bullet = bulletPrefabs;
            }
        }
        else
        {

        }
    }

    [PunRPC]
    void Damage()
    {
        if (Health > 0)
        {
            Health -= 20;
        }
        if (Health <= 0) // check health status
        {
            Health = 0; // make that Heath don't be < 0

            if (photonView.IsMine)
            {
                myCounts.RpcRespawn(); //Here you should to call counter
                photonView.transform.position = Vector2.zero;
                Health = 100;
            }
        }

    }
    // Update is called once per frame
    void Update()
    {
        if (photonView.IsMine)
        {
            dirX = CrossPlatformInputManager.GetAxis("Horizontal");
            if (dirX != 0)
            {
                barrel.up = Vector3.right * Mathf.Sign(dirX);
            }

            if (CrossPlatformInputManager.GetButtonDown("Jump"))
                Jump();

            if (CrossPlatformInputManager.GetButtonDown("Fire1"))
                Fire();
            
        }
        else
        {

        }
    }

    void FixedUpdate()
    {
        if (photonView.IsMine)
        {
            rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y);
        }
    }




    void Jump()
    {
        if (photonView.IsMine)
        {
            if (rb.velocity.y == 0)
                rb.AddForce(Vector2.up * jumpForce);
        }
    }

    void Fire()
    {
        
            var firedBullet = PhotonNetwork.Instantiate(bullet.name, barrel.position, barrel.rotation).GetComponent<Rigidbody2D>();
            firedBullet.AddForce(barrel.up * bulletSpeed);
        
    }

    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        if (stream.IsWriting)
        {
            stream.SendNext(Health);
        }
        else if (stream.IsReading)
        {
            Health = (float)stream.ReceiveNext();
        }
    }
    public void SetMaxHealth(int value)
    {
        if (photonView.IsMine)
        {
            slider.maxValue = value;
            // The property handles the rest anyway
            Health = value;
        }

    }
}

标签: unity3dphoton

解决方案


我认为在这种情况下你并不真的需要 RPC。

我看到你的角色 IPunObservable 并且,我猜,添加到 PhotonView。所以它的健康会自动同步。您还可以使用 PhotonNetwork 实例化子弹,这意味着它们也将同步并具有 PhotonView。

所以每个玩家都有所有同步的子弹和其他玩家。

这意味着,您只需要检查子弹是否来自其他玩家并在本地设置伤害(不用担心,结果会同步),如下所示:

. . .
    private void OnTriggerEnter2D(Collider2D col)
    {
        if (col.gameObject.CompareTag("Hurt"))
        {
            // if hurt object is not mine, take damage
            if (!col.gameObject.GetPhotonView().isMine) 
                Damage();
        }
        if (col.gameObject.tag == "PowerUp")
        {
            if (photonView.IsMine)
            {
                var powerup = col.GetComponent<PowerUp>();
                powerup.Pickup(this);
            }
            else
            {

            }

        }
        if (col.gameObject.CompareTag("Bullet"))
        {
            // if bullet is not mine, take damage
            if (!col.gameObject.GetPhotonView().isMine)
                Damage();
        }
        else
        {

        }
    }

    // no rpc
    void Damage()
    {
        if (!photonView.IsMine) // only player can change his life
            return;

        if (Health > 0)
        {
            Health -= 20;
        }
        if (Health <= 0) // check health status
        {
            myCounts.RpcRespawn(); //Here you should to call counter
            photonView.transform.position = Vector2.zero;
            Health = 100;
        }

    }

推荐阅读