2016-05-29 20 views
-1

後,我有法術的冷卻時間變量:變量的值會保持關閉應用

 private float nextFire = 0; 
public bool IsOffCooldown() 
{ 
    return Time.time > nextFire; 
} 

public void Cast(Transform spellSpawnerTransform) 
{ 
    nextFire = Time.time + FireRate; 
    Instantiate(this, spellSpawnerTransform.position, Quaternion.identity); 
} 

一旦我關閉應用程序中的變量nextFire保持它的IE先前的值,如果最後一次比賽持續了比方說30秒的nextFire變量將具有30f作爲起始值。爲什麼?如何解決這個問題?

UPDATE的完整代碼

public class Spell : MonoBehaviour 
{ 

public float FireRate; 
public float Damage; 
public float Speed; 
public GameObject SpellExplosion; 
public float nextFire = 0; 

public bool IsOffCooldown() 
{ 
    return Time.time > nextFire; 
} 

private void Update() 
{ 

} 

public void Cast(Transform spellSpawnerTransform) 
{ 
    nextFire = Time.time + FireRate; 
    Instantiate(this, spellSpawnerTransform.position, Quaternion.identity); 
} 
} 

SpellMover類:

public class SpellMover : MonoBehaviour 
{ 
private Rigidbody2D spellRigidBody; 
private Vector3 sp; 
private Vector2 dir; 
private Spell spell; 

private void Start() 
{ 
    spell = GetComponent<Spell>(); 
    spellRigidBody = GetComponent<Rigidbody2D>(); 
    sp = Camera.main.WorldToScreenPoint(transform.position); 
    dir = (Input.mousePosition - sp).normalized; 
    RotateTowardsMouse(); 
} 

private void Update() 
{  
    spellRigidBody.AddForce(dir * spell.Speed); 
} 

private void RotateTowardsMouse() 
{ 
    Transform target = spellRigidBody.transform; 
    Vector3 mouse_pos = Input.mousePosition; 
    Vector3 object_pos = Camera.main.WorldToScreenPoint(target.position); 
    mouse_pos.x = mouse_pos.x - object_pos.x; 
    mouse_pos.y = mouse_pos.y - object_pos.y; 
    float angle = Mathf.Atan2(mouse_pos.y, mouse_pos.x) * Mathf.Rad2Deg; 
    spellRigidBody.transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle)); 
} 

private void OnTriggerEnter2D(Collider2D other) 
{ 
    if (other.name == "Player" || other.name == "SpellSpawner" || other.name == "Boundary") 
    { 
     return; 
    } 
    Instantiate(spell.SpellExplosion, transform.position + transform.right, transform.rotation); 
} 
} 

球員運動類:

public class PlayerMovement : MonoBehaviour 
{ 
public float Speed; 
public GameObject SpellToUse; 

private Spell CurrentSpell; 
private bool IsAttacking = false; 
private Rigidbody2D playerRigidBody; 
private Animator playerAnimator; 
private SpriteRenderer playerRenderer; 
private GameObject skillSpawner; 

private void Start() 
{ 
    CurrentSpell = SpellToUse.GetComponent<Spell>(); 
    playerRigidBody = GetComponent<Rigidbody2D>(); 
    playerAnimator = GetComponent<Animator>(); 
    playerRenderer = GetComponent<SpriteRenderer>(); 
    skillSpawner = transform.FindChild("SpellSpawner").gameObject; 
} 

private void Update() 
{ 
    float horizontal = Input.GetAxis("Horizontal"); 
    float vertical = Input.GetAxis("Vertical"); 
    playerRigidBody.velocity = new Vector2(horizontal * Speed, vertical * Speed); 
    playerAnimator.SetFloat("Speed", horizontal); 
    if (Input.GetKey(KeyCode.Space) && CurrentSpell.IsOffCooldown()) 
    { 
     CurrentSpell.Cast(skillSpawner.transform); 
     IsAttacking = true; 
    } 
    if (Input.GetKeyUp(KeyCode.Space)) 
    { 
     IsAttacking = false; 
    } 
    playerAnimator.SetBool("IsAttacking", IsAttacking); 
    UpdateSpellSpawnerLocation(horizontal, vertical); 
} 

//separate script maybe ? 
private void UpdateSpellSpawnerLocation(float inputHorizontal, float inputVertical) 
{ 
    if (inputHorizontal < 0) 
    { 
     //left 
     skillSpawner.transform.position = new Vector2(playerRigidBody.transform.position.x - playerRenderer.bounds.size.x/3, playerRigidBody.transform.position.y); 
    } 
    else if (inputHorizontal > 0) 
    { 
     //right 
     skillSpawner.transform.position = new Vector2(playerRigidBody.transform.position.x + playerRenderer.bounds.size.x/3, playerRigidBody.transform.position.y); 
    } 
    else if (inputVertical > 0) 
    { 
     //up 
     skillSpawner.transform.position = new Vector2(playerRigidBody.transform.position.x, playerRigidBody.transform.position.y + playerRenderer.bounds.size.y/3); 
    } 
    else if (inputVertical < 0) 
    { 
     //down 
     skillSpawner.transform.position = new Vector2(playerRigidBody.transform.position.x, playerRigidBody.transform.position.y - playerRenderer.bounds.size.y/2); 
    } 
} 
} 
+0

你的代碼中的任何位置有'PlayerPrefs.SetFloat'或'PlayerPrefs.GetString'嗎?也許這個值在退出時保存並且在開始時加載...... – Programmer

+0

這幾乎是我在這個類中的所有代碼,並且您可以看到它是私有的,所以它不能從其他任何地方設置,我只有幾個變量聲明這一個的頂部。我改變它的唯一值是'Cast'方法。我將'nextFire'變量設置爲public,所以我可以在unity編輯器中看到它,我可以清楚地看到它保存了以前的值。 – PreqlSusSpermaOhranitel

+0

當您點擊停止,然後再次播放時,舊值仍然存在?我沒有看到任何在上面的代碼中保存你的價值的東西。你介意把這個項目放在github中,並把它連接到這裏?我會看看問題是什麼。 – Programmer

回答

1

nextFire變量是在MonoBehaviour並且是公開的。這意味着Unity會將價值序列化並通過檢查員訪問。從那裏開始,它會始終加載在檢查員設置的值。這可能是因爲你在遊戲模式下設置了一些值,所以它仍然存在。您可以將此檢查器值視爲「默認值」,運行時的更改將不會保存,但是在編輯模式下它們是。

不保存價值,但保留變量公共添加非序列化屬性是這樣的:

[System.NonSerialized] 
public float nextFire = 0f; 

但我看不出有任何理由爲這是一個公共變量。把它變成私人的,它應該起作用。或者將其設置爲公開獲取和私人設置的屬性,因此它不會在檢查器中序列化。

讀完之後,您已將變量設置爲公開,因爲您想在檢查器中看到它:如果它是公開的,它也將被Unity保存和加載。如果您只想檢查調試值,右鍵單擊檢查器右上角的小圖標,然後選擇調試模式。它也將以這種方式顯示私有變量。然後只要nextFire私人。或者,您可以將其保留爲公開,並將其序列化,但在Awake()中將其設置爲零。

public float nextFire; 

void Awake() 
{ 
    nextFire = 0f; 
} 

接下來,看起來您可能正在更改場景中預製件的值而不是GameObject的值。請注意,您需要保存實例化預製件的副本,然後更改副本上的值,而不是原始值,否則更改也會通過播放模式持續進行。預製件始終保存。

public GameObject spellPrefab; 
private GameObject runtimeSpell; 
private float nextFire; 

void Awake() 
{ 
    runtimeSpell = Instantiate(spellPrefab); 
} 

您可以將後綴預製添加到組合屋舉行,以確保你不小心在運行時修改它們的變量。

+0

使用'[System.NonSerialized]'做的工作使變量私人並不能解決問題。有一個問題我知道,即時更改預製而不是克隆,聲明gameobject runtimeSpell不會改變任何東西。 – PreqlSusSpermaOhranitel