[英]C# - RandomRangeInt is not allowed to be called from a MonoBehaviour constructor
In the code for player attack, I tried to add a critical chance and a critical multiply system.在玩家攻击的代码中,我尝试添加一个临界机会和一个临界乘法系统。 The code for which is below
代码如下
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);
}
}
When this is used in Unity I get the errors当它在 Unity 中使用时,我得到了错误
UnityException: RandomRangeInt is not allowed to be called from a MonoBehaviour constructor (or instance field initializer), call it in Awake or Start instead. UnityException: RandomRangeInt 不允许从 MonoBehaviour 构造函数(或实例字段初始化程序)调用,而是在 Awake 或 Start 中调用。 Called from MonoBehaviour 'PlayerCombat'.
从 MonoBehaviour 'PlayerCombat' 调用。 See "Script Serialization" page in the Unity Manual for further details.
有关详细信息,请参阅 Unity 手册中的“脚本序列化”页面。 UnityEngine.Random.Range (System.Int32 minInclusive, System.Int32 maxExclusive) (at <07c89f7520694139991332d3cf930d48>:0) PlayerCombat..ctor () (at Assets/Scripts/PlayerCombat.cs:44)
UnityEngine.Random.Range (System.Int32 minInclusive, System.Int32 maxExclusive) (at <07c89f7520694139991332d3cf930d48>:0) PlayerCombat..ctor () (at Assets/Scripts/PlayerCombat.cs:44)
and和
UnityException: RandomRangeInt is not allowed to be called from a MonoBehaviour constructor (or instance field initializer), call it in Awake or Start instead. UnityException: RandomRangeInt 不允许从 MonoBehaviour 构造函数(或实例字段初始化程序)调用,而是在 Awake 或 Start 中调用。 Called from MonoBehaviour 'PlayerCombat'.
从 MonoBehaviour 'PlayerCombat' 调用。 See "Script Serialization" page in the Unity Manual for further details.
有关详细信息,请参阅 Unity 手册中的“脚本序列化”页面。 UnityEngine.Random.Range (System.Int32 minInclusive, System.Int32 maxExclusive) (at <07c89f7520694139991332d3cf930d48>:0) PlayerCombat..ctor () (at Assets/Scripts/PlayerCombat.cs:44)
UnityEngine.Random.Range (System.Int32 minInclusive, System.Int32 maxExclusive) (at <07c89f7520694139991332d3cf930d48>:0) PlayerCombat..ctor () (at Assets/Scripts/PlayerCombat.cs:44)
I am new to coding and working on a game with my friend, if I leave the int damageCalc empty or the if statements empty I get no errors.我不熟悉编码和与朋友一起玩游戏,如果我将 int damageCalc 留空或 if 语句为空,我不会收到任何错误。 But no matter what I try what I add in it brings back errors.
但无论我尝试添加什么,它都会带来错误。
(sorry if this is formatted bad first question on StackOverflow) (对不起,如果这是在 StackOverflow 上的第一个问题的格式错误)
Just exactly as the error tells you, you can not do正如错误告诉你的那样,你不能做
public int randValue = Random.Range (0,101);
on field declaration time but rather need to assign this on runtime via eg在字段声明时间,但需要通过例如在运行时分配它
public int randValue;
// private void Awake()
// or
private void Start()
{
randValue = Random.Range (0,101);
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.