簡體   English   中英

C# - 不允許從 MonoBehaviour 構造函數調用 RandomRangeInt

[英]C# - RandomRangeInt is not allowed to be called from a MonoBehaviour constructor

在玩家攻擊的代碼中,我嘗試添加一個臨界機會和一個臨界乘法系統。 代碼如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;

public class PlayerCombat : NetworkBehaviour
{
/*public enum weaponType : int
{
    dagger = 0,
    shortSword = 0,
    longSword = 0,

    spear = 1,
    halberd = 1,

    battleAxe = 2,
    morningStar = 2
}*/
/*public enum shieldType : int
{
    basic = 0,
}*/

public enum cardinalDirection : int
{
    Up = 0,
    Right = 1,
    Down = 2,
    Left = 3
}

[Header("Weapon")]
public MeleeWeapon currentWeapon;

public Vector2 attackCenter =  new Vector2(0, -0.2f);

private bool attacking = false;
private bool cooldownOver = true;

[Header("Critical")]
public float critChance = 75;
public int critMultiplier = 20;
public int randValue = Random.Range (0,101);

[Header("Shield")]
public Shield currentShield;

[HideInInspector]
public bool shielding = false;


//Other
[HideInInspector]
public cardinalDirection attackDirection;
private Animator anim;
private PlayerController controller;

[Header("Utility-")]
[SerializeField]
private bool drawGizmos = false;

void Start() 
{
    anim = GetComponent<Animator>();
    controller = GetComponent<PlayerController>();
}

void Update()
{
    anim.SetInteger("Shield Type", (int)currentShield.type);
    anim.SetInteger("Attack Type", (int)currentWeapon.type);

    attackDirection = (cardinalDirection)controller.cardinalFaceDirection;

    if (!isLocalPlayer) return;

    if (Input.GetButtonDown("Attack") && !attacking && cooldownOver && !shielding)
    {
        anim.SetTrigger("Attack");

        StartCoroutine("Attack");
    }

    if (Input.GetButton("Shield") && !attacking)
    {
        //Animation stuff

        shielding = true;
    }
    else
    {
        shielding = false;
    }

    if (attacking || shielding)
    {
        controller.canMove = false;
    }
    else
    {
        controller.canMove = true;
    }

    ManageShield();
}

int damageCalc()
{
    if(randValue < critChance)
    {
        return currentWeapon.damage*critMultiplier;
    }
    else
    {
        return currentWeapon.damage;
    }
}

IEnumerator Attack()
{
    attacking = true;
    cooldownOver = false;

    //Quick delay to make the attack feel more natural
    yield return new WaitForSeconds(0.1f);

    //Attack Logic
    Collider2D[] hits = Physics2D.OverlapCircleAll((Vector2)transform.position + 
attackCenter, currentWeapon.range);
    
    foreach (Collider2D currentHit in hits)
    {
        if(currentHit.tag == "Enemy")
        {
            if (attackDirection == 
(cardinalDirection)controller.CardinalDirection(currentHit.transform.position - 
transform.position))
            {
                
                Vector2 hitDirection = currentHit.gameObject.transform.position - 
transform.position;
                currentHit.gameObject.GetComponent<BasicZombie> 
()?.TakeDamage(currentWeapon.damage, hitDirection, currentWeapon.knockback);
            }
            else
            {
                Debug.Log("Facing wrong direction");
            }
        }
    }

    //The rest of the delay
    yield return new WaitForSeconds(0.2f);
    attacking = false;
    //Weapon cooldown delay
    yield return new WaitForSeconds(currentWeapon.cooldown);
    cooldownOver = true;
}

void ManageShield()
{
    if(shielding)
    {
        anim.SetBool("Shielding", true);
    }
    else
    {
        anim.SetBool("Shielding", false);
    }
}


void OnDrawGizmos()
{
    if(!drawGizmos) return;
    Gizmos.DrawWireSphere((Vector2)transform.position + attackCenter, 
currentWeapon.range);
}

}

當它在 Unity 中使用時,我得到了錯誤

UnityException: RandomRangeInt 不允許從 MonoBehaviour 構造函數(或實例字段初始化程序)調用,而是在 Awake 或 Start 中調用。 從 MonoBehaviour 'PlayerCombat' 調用。 有關詳細信息,請參閱 Unity 手冊中的“腳本序列化”頁面。 UnityEngine.Random.Range (System.Int32 minInclusive, System.Int32 maxExclusive) (at <07c89f7520694139991332d3cf930d48>:0) PlayerCombat..ctor () (at Assets/Scripts/PlayerCombat.cs:44)

UnityException: RandomRangeInt 不允許從 MonoBehaviour 構造函數(或實例字段初始化程序)調用,而是在 Awake 或 Start 中調用。 從 MonoBehaviour 'PlayerCombat' 調用。 有關詳細信息,請參閱 Unity 手冊中的“腳本序列化”頁面。 UnityEngine.Random.Range (System.Int32 minInclusive, System.Int32 maxExclusive) (at <07c89f7520694139991332d3cf930d48>:0) PlayerCombat..ctor () (at Assets/Scripts/PlayerCombat.cs:44)

我不熟悉編碼和與朋友一起玩游戲,如果我將 int damageCalc 留空或 if 語句為空,我不會收到任何錯誤。 但無論我嘗試添加什么,它都會帶來錯誤。

(對不起,如果這是在 StackOverflow 上的第一個問題的格式錯誤)

正如錯誤告訴你的那樣,你不能做

public int randValue = Random.Range (0,101);

在字段聲明時間,但需要通過例如在運行時分配它

public int randValue;

// private void Awake()
// or
private void Start()
{
     randValue = Random.Range (0,101);

     ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM