2016-05-29 7 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 хранит это предыдущее значение, то есть, если в последний раз игра продолжалась, скажем, 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' общедоступной, поэтому я могу увидеть ее в редакторе единства, и я вижу, что она явно сохраняет прежнее значение. – PreqlSusSpermaOhranitel

+0

Когда вы нажимаете кнопку «Стоп» и затем снова играете, старое значение все еще существует? Я не вижу ничего, что экономит ваше значение в коде выше. Вы хотите разместить проект в github и связать его здесь? Я посмотрю и посмотрю, в чем проблема. – Programmer

ответ

1

nextFire переменная на MonoBehaviour и общественности. Это означает, что Unity будет сериализовать значение и сделать его доступным через инспектора. Оттуда он всегда будет загружать значение, которое устанавливается в инспекторе при запуске игры. Возможно, вы установили какое-то значение там, а не в режиме воспроизведения, поэтому оно было сохранено. Вы можете подумать об этом значении инспектора как о значении «по умолчанию», изменения во время выполнения не будут сохранены, но в режиме редактирования они есть.

Чтобы не сохранять значение, но сохранить переменную общественного добавить атрибут NonSerialized так:

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

Но я не вижу никаких оснований для этого, чтобы быть публичной переменной. Сделайте его частным, и он должен работать. Или сделать его собственностью с публичным и частным набором, поэтому он не будет сериализован в инспекторе.

После прочтения, что вы сделали переменную общедоступной, потому что вы хотели видеть ее в инспекторе: если она общедоступна, она также будет сохранена и загружена Unity. Если вы хотите только проверить значение для отладки, щелкните правой кнопкой мыши на маленьком значке в верхнем правом углу инспектора и выберите debug. В этом случае также будут показаны частные переменные. Затем просто сделайте nextFire частный. Кроме того, вы можете оставить его общедоступным, а также его сериализовать, но затем в Awake() установите его на ноль.

public float nextFire; 

void Awake() 
{ 
    nextFire = 0f; 
} 

Далее, это выглядит, как вы, возможно, изменяя значения из сборного вместо GameObject в сцене. Имейте в виду, что вам нужно сохранить копию инстанцированного сборника, а затем изменить значения на копии, а не оригинал, иначе изменения также сохраняются в режиме воспроизведения. Сборники всегда сохраняются.

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

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

Вы можете добавить постфикс Сборных переменных холдинговой Prefabs, чтобы убедиться, что вы случайно не изменить их во время выполнения.

+0

с помощью '[System.NonSerialized]' выполнило задание, делающее переменную private, не решает проблему. Один вопрос, который я знаю, что im изменяет prefab вместо clone, объявляя gameobject runtimeSpell, ничего не меняет. – PreqlSusSpermaOhranitel

Смежные вопросы