I just cant manage to add a public object to the dcript i have.
There is code:
public class Player : MonoBehaviour {
public string charName = "";
public int currentLevel = 0;
public int experiense = 0;
public int strength = 1;
public int agility = 1;
public int maxHealth = 30;
public float currentHealth = 30;
public int maxActionPoints = 5;
public int currentLevelPoints = 10;}
there is another script where i want to add a public property with this class
public class CharManager : MonoBehaviour {
public GameObject currentCharacter;
public GameObject charMenu;
public Player currentPlayerStats;
public void changeCharacter(GameObject character)
{
if (currentCharacter){
saveCharacter ();
}
currentCharacter = character;
loadSavedInfo ();
}
void loadSavedInfo()
{
string playerJson = "";
if (currentCharacter.tag== "Man")
{
if (File.Exists(Application.persistentDataPath +"/Char1.json"))
{
playerJson = File.ReadAllText(Application.persistentDataPath +"/Char1.json");
}
}
else
{
if (File.Exists(Application.persistentDataPath +"/Char2.json"))
{
playerJson = File.ReadAllText(Application.persistentDataPath +"/Char2.json");
}
}
if (playerJson != string.Empty)
{
Player thePlayer = JsonConvert.DeserializeObject<Player>(playerJson);
currentPlayerStats = thePlayer;
}
else
{
currentPlayerStats = gameObject.AddComponent<Player>() as Player;
}
}
This code add NEW player component and currentPlayerStats have class CharManager... what am i doing wrong?
Any help is very appreciated!
gameObject.AddComponent() adds a MonoBehaviour derived component to the game object. Player does not derive from MonoBehaviour thus it cannot be added
Looks like Player is just a regular class, so you can just create an object of that class
Player currentPlayerStats = new Player();
I figured it out.
Player class must be non MonoBehaviour class. A class where i have to access the player class should have a public property:
public Player thePlayer;
not
public GameObject thePlayer;
Thanks everyone!
Related
I was working on a xml saving system for my game but whenever I instantiate my prefab all of my public transforms, animators etc have gone null. I found this out by going into debug mode and looking into my player script. in my create actor function in my Game controller script I have created a player movement state machine script from a video series I watched. Inside it has all of the states, animations etc.
Here is my Player script code:
using UnityEngine;
using Cinemachine;
namespace GenshinImpactMovementSystem
{
[RequireComponent(typeof(PlayerInput))]
[RequireComponent(typeof(PlayerResizableCapsuleCollider))]
public class Player : MonoBehaviour
{
[field: Header("References")]
[field: SerializeField] public PlayerSO Data { get; private set; }
[field: Header("Collisions")]
[field: SerializeField] public PlayerLayerData LayerData { get; private set; }
[field: Header("Camera")]
[field: SerializeField] public PlayerCameraRecenteringUtility CameraRecenteringUtility { get; set; }
[field: Header("Animations")]
[field: SerializeField] public PlayerAnimationData AnimationData { get; private set; }
public Rigidbody Rigidbody { get; private set; }
public Animator Animator { get; private set; }
public PlayerInput Input { get; private set; }
public PlayerResizableCapsuleCollider ResizableCapsuleCollider { get; private set; }
public Transform MainCameraTransform { get; private set; }
public PlayerMovementStateMachine movementStateMachine;
public IKController IKController;
public Transform cameraPointLookAt;
public CinemachineVirtualCamera cam;
private void Awake()
{
CameraRecenteringUtility.Initialize();
AnimationData.Initialize();
Rigidbody = GetComponent<Rigidbody>();
Animator = GetComponentInChildren<Animator>();
Input = GetComponent<PlayerInput>();
ResizableCapsuleCollider = GetComponent<PlayerResizableCapsuleCollider>();
MainCameraTransform = Camera.main.transform;
movementStateMachine = new PlayerMovementStateMachine(this);
}
private void Start()
{
movementStateMachine.ChangeState(movementStateMachine.IdlingState);
}
private void Update()
{
movementStateMachine.HandleInput();
movementStateMachine.Update();
}
private void FixedUpdate()
{
movementStateMachine.PhysicsUpdate();
}
private void OnTriggerEnter(Collider collider)
{
movementStateMachine.OnTriggerEnter(collider);
}
private void OnTriggerExit(Collider collider)
{
movementStateMachine.OnTriggerExit(collider);
}
public void OnMovementStateAnimationEnterEvent()
{
movementStateMachine.OnAnimationEnterEvent();
}
public void OnMovementStateAnimationExitEvent()
{
movementStateMachine.OnAnimationExitEvent();
}
public void OnMovementStateAnimationTransitionEvent()
{
movementStateMachine.OnAnimationTransitionEvent();
}
}
}
Here is my Game Controller code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Cinemachine;
using TMPro;
namespace GenshinImpactMovementSystem
{
public class GameController : MonoBehaviour
{
public Button saveButton;
public Button loadButton;
public CinemachineVirtualCamera camera;
public const string playerPath = "Prefabs/Player";
private static string dataPath = string.Empty;
void Awake()
{
if (Application.platform == RuntimePlatform.IPhonePlayer)
{
dataPath = System.IO.Path.Combine(Application.persistentDataPath, "Resources/actors.xml");
}
else
{
dataPath = System.IO.Path.Combine(Application.dataPath, "Resources/actors.xml");
}
}
void Start()
{
CreateActor(playerPath, new Vector3(0, 0, 0), Quaternion.identity);
}
public static Actor CreateActor(string path, Vector3 position, Quaternion rotation)
{
GameObject prefab = Resources.Load<GameObject>(path);
GameObject go = GameObject.Instantiate(prefab, position, rotation) as GameObject;
Player playerScript = go.GetComponent<Player>();
Transform cameraLookAt = playerScript.cameraPointLookAt;
CinemachineVirtualCamera cam = FindObjectOfType<CinemachineVirtualCamera>();
cam.Follow = cameraLookAt;
cam.LookAt = cameraLookAt;
playerScript.CameraRecenteringUtility.VirtualCamera = cam;
Actor actor = go.GetComponent<Actor>() ?? go.AddComponent<Actor>();
return actor;
}
public static Actor CreateActor(ActorData data, string path, Vector3 position, Quaternion rotation)
{
GameObject prefab = Resources.Load<GameObject>(path);
GameObject go = GameObject.Instantiate(prefab, position, rotation);
Actor actor = go.GetComponent<Actor>() ?? go.AddComponent<Actor>();
actor.data = data;
return actor;
}
void OnEnable()
{
saveButton.onClick.AddListener(delegate {SaveData.Save(dataPath, SaveData.actorContainer);});
loadButton.onClick.AddListener(delegate {SaveData.Load(dataPath);});
}
void OnDisable()
{
saveButton.onClick.RemoveListener(delegate {SaveData.Save(dataPath, SaveData.actorContainer);});
loadButton.onClick.RemoveListener(delegate {SaveData.Load(dataPath);});
}
}
}
I thought I would show you the player camera recentering utility script because there is an error there also:
using Cinemachine;
using System;
using UnityEngine;
namespace GenshinImpactMovementSystem
{
[Serializable]
public class PlayerCameraRecenteringUtility
{
[field: SerializeField] public CinemachineVirtualCamera VirtualCamera { get; set; }
[field: SerializeField] public float DefaultHorizontalWaitTime { get; private set; } = 0f;
[field: SerializeField] public float DefaultHorizontalRecenteringTime { get; private set; } = 4f;
private CinemachinePOV cinemachinePOV;
public void Initialize()
{
cinemachinePOV = VirtualCamera.GetCinemachineComponent<CinemachinePOV>();
}
public void EnableRecentering(float waitTime = -1f, float recenteringTime = -1f, float baseMovementSpeed = 1f, float movementSpeed = 1f)
{
cinemachinePOV.m_HorizontalRecentering.m_enabled = true;
cinemachinePOV.m_HorizontalRecentering.CancelRecentering();
if (waitTime == -1f)
{
waitTime = DefaultHorizontalWaitTime;
}
if (recenteringTime == -1f)
{
recenteringTime = DefaultHorizontalRecenteringTime;
}
recenteringTime = recenteringTime * baseMovementSpeed / movementSpeed;
cinemachinePOV.m_HorizontalRecentering.m_WaitTime = waitTime;
cinemachinePOV.m_HorizontalRecentering.m_RecenteringTime = recenteringTime;
}
public void DisableRecentering()
{
cinemachinePOV.m_HorizontalRecentering.m_enabled = false;
}
}
}
I am working on a dialogue and questing system for a 2d game I am working on. I am attempting to have multiple NPCs that will give different quests with different dialogue that is unique to each quest. I attempt to trigger my dialogue whenever a player presses the E key. Currently my game displays the dialogue whenever the player becomes in contact with the NPCs collider. The dialogue also begins with the second sentence of the dialogue array. Additionally, once the player has interacted with multiple npcs, the dialogue for all npc becomes the dialogue of the last npc that was interacted with.
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
public class QuestGiver : NPC
{
public bool AssignedQuest { get; set; }
public bool Helped { get; set; }
[SerializeField]
private GameObject quests;
[SerializeField]
private string questType;
private Quest Quest { get; set; }
public CharacterController2D player;
public GameObject questWindow;
public Text titleText;
public Text descriptionText;
public Text expRewardText;
public Text currencyRewardText;
private void Start()
{
}
public override void Interact()
{
if (!AssignedQuest && !Helped)
{
DialogueManager.Instance.AddNewDialogue(dialogue, name);
AssignQuest();
}
else if (AssignedQuest && !Helped)
{
CheckQuest();
}
else
{
DialogueManager.Instance.AddNewDialogue(Quest.completedDialogue, name);
}
}
void AssignQuest()
{
AssignedQuest = true;
Quest = (Quest)quests.AddComponent(Type.GetType(questType));
}
void CheckQuest()
{
if (Quest.Completed)
{
Quest.GiveReward();
Helped = true;
AssignedQuest = false;
DialogueManager.Instance.AddNewDialogue(Quest.rewardDialogue, name);
Destroy(quests.GetComponent(Type.GetType(questType)));
}
else
{
DialogueManager.Instance.AddNewDialogue(Quest.inProgressDialogue, name);
}
}
public void OpenQuestWindow()
{
questWindow.SetActive(true);
titleText.text = Quest.QuestName;
descriptionText.text = Quest.Description;
expRewardText.text = Quest.ExpRewards.ToString();
currencyRewardText.text = Quest.CurrencyReward.ToString();
}
public void AcceptQuest()
{
questWindow.SetActive(false);
Quest.Completed = false;
player.questsList.Add(Quest);
}
}
This is the Quest script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
[System.Serializable]
public class Quest : MonoBehaviour
{
public List<QuestGoal> Goals { get; set; } = new List<QuestGoal>();
public string[] inProgressDialogue, rewardDialogue, completedDialogue;
public string QuestName { get; set; }
public string Description { get; set; }
public int ExpRewards { get; set; }
public int CurrencyReward { get; set; }
public Item ItemReward { get; set; }
public bool Completed { get; set; }
public void CheckGoals()
{
Completed = Goals.All(q => q.Completed);
if (Completed) GiveReward();
}
public void GiveReward()
{
if (ItemReward != null)
Inventory.inventory.Add(ItemReward);
}
This is the NPC:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NPC : Interactable
{
public string[] dialogue;
public string name;
public override void Interact()
{
base.Interact();
DialogueManager.Instance.AddNewDialogue(dialogue, name);
Debug.Log("Interacting with " + name);
}
public void TriggerDialogue()
{
FindObjectOfType<DialogueManager>().AddNewDialogue(dialogue, name);
}
}
This is my dialogue script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
public class DialogueManager : MonoBehaviour
{
#region
public static DialogueManager Instance { get; set; }
public GameObject dialoguePanel;
private void Awake()
{
dialoguePanel.SetActive(false);
if (Instance != null && Instance != this)
{
Debug.Log(Instance);
Destroy(Instance);
}
else
{
Instance = this;
}
}
#endregion
public Text nameText, dialogueText;
public Button continueButton;
public Animator animator;
public string npcName;
int dialogueIndex;
public List<string> dialogueLines = new List<string>();
void Start()
{
}
public void AddNewDialogue(string[] lines, string npcName)
{
dialogueIndex = 0;
dialogueLines = new List<string>();
foreach (string line in lines)
{
dialogueLines.Add(line);
}
this.npcName = npcName;
Debug.Log(dialogueLines.Count);
Debug.Log(npcName);
CreateDialogue();
}
public void CreateDialogue()
{
nameText.text = npcName;
dialogueText.text = dialogueLines[dialogueIndex];
dialoguePanel.SetActive(true);
animator.SetBool("IsOpen", true);
ContinueDialogue();
}
public void ContinueDialogue()
{
if (dialogueIndex < dialogueLines.Count - 1)
{
dialogueIndex++;
dialogueText.text = dialogueLines[dialogueIndex];
}
else
{
EndDialogue();
}
StopAllCoroutines();
StartCoroutine(TypeSentence(dialogueText.text));
}
IEnumerator TypeSentence (string sentence)
{
dialogueText.text = "";
foreach (char letter in sentence.ToCharArray())
{
dialogueText.text += letter;
yield return null;
}
}
void EndDialogue()
{
animator.SetBool("IsOpen", false);
Debug.Log("End of conversation");
}
}
This is part of the Player controller:
using UnityEngine;
using UnityEngine.Events;
using Spine.Unity;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class CharacterController2D : MonoBehaviour
{
private GameObject triggeringNpc;
public GameObject npcText;
public List<Quest> questsList = new List<Quest>();
private bool triggering;
private void OnTriggerEnter2D(Collider2D other)
{
Interactable interactable = other.gameObject.GetComponent<Interactable>();
if (interactable != null)
{
interactable.Interact();
}
if (other.tag == "NPC")
{
triggering = true;
triggeringNpc = other.gameObject;
}
if (other.tag == "QuestGiver")
{
triggering = true;
triggeringNpc = other.gameObject;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.tag == "NPC")
{
triggering = false;
triggeringNpc = null;
}
if (other.tag == "QuestGiver")
{
triggering = false;
triggeringNpc = null;
}
}
private void Update()
{
if (triggering)
{
npcText.SetActive(true);
if (Input.GetKeyDown(KeyCode.E))
{
FindObjectOfType<QuestGiver>().TriggerDialogue();
}
}
else
{
npcText.SetActive(false);
}
}
}
Thank you in advance, sorry for the long post.
Dialogue starting on the second line:
In the CreateDialogue() method, at the end you are calling ContinueDialogue(). So you create dialogue and then immediately tell it to go to the next line. I think instead you might want to be calling StartCoroutine(TypeSentence(dialogueText.text)) at the end of CreateDialogue().
Interaction issues:
You're calling Interact() at the beginning of OnTriggerEnter2D by doing interactable.Interact(). Here, erase all the code inside your OnTriggerEnter2D method and replace it with this.
if (other.tag == "NPC" || other.tag == "QuestGiver") {
triggering = true;
triggeringNpc = other.gameObject;
} else if (interactable != null) { interactable.Interact(); }
I have a list, list_of_targetable, into which I spawn enemy instances. I can see during play in the inspector that the instances are spawning correctly and being put in the list correctly.
When I try to reference those instances, from within the same script, they seemly do not exist, and the list.Count returns 0. Furthermore, the way I am calling TargetEnemySlot1 is via button, so long after Start, when the enemies are initialized.
What gives?
public class Targeting : MonoBehaviour
{
public List<Combatant> current_targets;
public List<Combatant> list_of_targetable;
public void TargetEnemySlot1()
{
Debug.Log(list_of_targetable.Count);
current_targets.Add(list_of_targetable[0]);
current_targets[0].is_target = true;
current_targets[0].targeting_panel.SetActive(false);
}
}
Things that interact directly with the lists:
public class AbAttack : MonoBehaviour, IAbility
{
public Targeting targeting_for_attack;
public int block_attack_damage = 10;
public int block_attack_repeats = 2;
public bool needs_targets = true;
public bool targets_allies = false;
public bool targets_enemies = true;
public int number_of_targets = 1;
public void Use()
{
if (needs_targets == true)
{
if (targets_enemies == true)
{
foreach (Combatant enemy in targeting_for_attack.list_of_targetable)
{
enemy.targeting_panel.SetActive(true);
}
}
}
}
public void Enact()
{
foreach (Combatant enemy in targeting_for_attack.current_targets)
{
for (int i = 0; i < block_attack_repeats; i++)
{
enemy.health = enemy.health - block_attack_damage;
}
}
}
}
public class EnemySpawner : MonoBehaviour
{
public List<Combatant> CombatantList = new List<Combatant>();
public List<Combatant> CombatantInWaitingList = new List<Combatant>();
public List<Combatant> CombatantInCombatList = new List<Combatant>();
Inventory inventory;
public List <GameObject> targeting_panel;
public Targeting targeting_panel_targeting;
public Sprite icon1;
// Start is called before the first frame update
void Start()
{
inventory = Inventory.instance;
DrainList();
SpawnList();
}
public void DrainList()
{
List<Combatant> ToRemoveList = new List<Combatant>();
foreach (Combatant item in CombatantInWaitingList)
{
if (CombatantInCombatList.Count <= 3)
{
CombatantInCombatList.Add(item);
ToRemoveList.Add(item);
}
}
foreach (Combatant item in ToRemoveList)
{
CombatantInWaitingList.Remove(item);
}
}
public void SpawnList()
{
List<Combatant> ToRemoveList = new List <Combatant>();
foreach (Combatant item in CombatantInCombatList)
{
if (Inventory.instance.items1.Count == 0)
{
Combatant data1 = Combatant.CreateInstance("spider", icon1, targeting_panel[0]);
Inventory.instance.items1.Add(data1);
targeting_panel_targeting.list_of_targetable.Add(data1);
ToRemoveList.Add(item);
}
if (Inventory.instance.items1.Count == 1)
{
Combatant data1 = Combatant.CreateInstance("spider", icon1, targeting_panel[1]);
Inventory.instance.items1.Add(data1);
targeting_panel_targeting.list_of_targetable.Add(data1);
ToRemoveList.Add(item);
}
if (Inventory.instance.items1.Count == 2)
{
Combatant data1 = Combatant.CreateInstance("spider", icon1, targeting_panel[2]);
Inventory.instance.items1.Add(data1);
targeting_panel_targeting.list_of_targetable.Add(data1);
ToRemoveList.Add(item);
}
}
foreach (Combatant item in ToRemoveList)
{
// Add new combataant at that list location FIRST
CombatantInCombatList.Remove(item);
}
}
}
The IN GAME inspector with the instances spawned correctly:
http://prntscr.com/o629xb
Well i am trying to save my Game Stats using system serializable but i am not being able to do it i have two scripts one named "Stats" and another named "SaveLoad" in the "Stats" i have my serializables and in the "SaveLoad" i have my saving and loading script i followed the instructions here
https://gamedevelopment.tutsplus.com/tutorials/how-to-save-and-load-your-players-progress-in-unity--cms-20934
But since i am a begginer with this stuff and my seriazable data differs i am having issues on saving it.
My "Stats"
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Stats : MonoBehaviour {
public static int coins = 0;
public static int totalcoins = 0;
public static int score = 0;
public static int personalbest = 0;
public static float UmbrellaSpeed = 0.1f;
public static float currentumbdur = 500;
public static int CarrotSpawnRateLVL = 1;
public static float CarrotSpawnRate = 60f;
public static int CarrotSpawnRateUpgradeCost = 15;
public static int UmbrellaDurabilityLVL = 1;
public static float UmbrellaDurability = 500;
public static int UmbrellaDurabilityUpgradeCost = 30;
public static int UmbrellaSizeLVL = 1;
public static float UmbrellaSize = 0f;
public static int UmbrellaSizeUpgradeCost = 25;
public static int CarrotEffectLVL = 1;
public static float CarrotEffect = 20;
public static int CarrotEffectUpgradeCost = 25;
public static int HealthRegenLVL = 1;
public static float HealthRegenTime = 4f;
public static int HealthRegenCost = 100;
public static int BuyTreesCost = 250;
public static int Tree1Bought = 0;
public static float Tree1Size = 0;
public static int Tree1SizeLVL = 1;
public static int Tree1SizeUpgradeCost = 50;
public static int Tree2Bought = 0;
public static float Tree2Size = 0;
public static int Tree2SizeLVL = 1;
public static int Tree2SizeUpgradeCost = 50;
public static int Tree3Bought = 0;
public static float Tree3Size =0;
public static int Tree3SizeLVL = 1;
public static int Tree3SizeUpgradeCost = 50;
// Use this for initialization
void Start () {
InvokeRepeating ("AddCoins", 4.0f, 2.0f);
InvokeRepeating ("AddScore", 1.5f, 1.5f);
}
// Update is called once per frame
void Update () {
if (score > personalbest) {
personalbest = score;
}
//Debug.Log (" " + coins);
}
void AddCoins (){
if (BunnyScript.BunnyAlive == true) {
coins += 1;
}
}
void AddScore (){
if (BunnyScript.BunnyAlive == true) {
score += 1;
}
}
}
And my "SaveLoad" script
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public static class SaveLoad {
public static List<Stats> savedGames = new List<Stats>();
public static void Save (){
savedGames.Add(Stats);
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create (Application.persistentDataPath + "/savedGames.gd");
bf.Serialize(file, SaveLoad.savedGames);
file.Close();
}
public static void Load (){
if (File.Exists (Application.persistentDataPath + "/savedGames.gd")) {
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/savedGames.gd", FileMode.Open);
SaveLoad.savedGames = (List<Stats>)bf.Deserialize(file);
file.Close();
}
}
}
You should not serialize a MonoBehaviour class for storing data, there is so much below that you cannot see in this type that it is just wrong.
Also, you have a list of stats object but it is only containing static value so all your Stats objects have same content.
using UnityEngine;
using System.Collections;
public class Stats : MonoBehaviour
{
StatContainer stats = new StatContainer();
// Use this for initialization
void Start () {
InvokeRepeating ("AddCoins", 4.0f, 2.0f);
InvokeRepeating ("AddScore", 1.5f, 1.5f);
}
// Update is called once per frame
void Update () {
this.stats.Update();
}
void AddCoins (){
stats.AddCoins();
}
void AddScore (){
stats.AddScore();
}
}
[Serializable]
public class StatContainer
{
public int coins = 0;
public int totalcoins = 0;
public int score = 0;
public int personalbest = 0;
public float UmbrellaSpeed = 0.1f;
public float currentumbdur = 500;
public int CarrotSpawnRateLVL = 1;
public float CarrotSpawnRate = 60f;
public int CarrotSpawnRateUpgradeCost = 15;
// and the rest
public void Update(){
if (statscore > personalbest) {
personalbest = score;
}
}
}
Now you can serialize the StatContainer in the same manner you were.
Because there is no static method anymore, each StatContainr on each Stats component is unique and not sharing anything with others.
And bonus, you can even perform unit test more easily with StatContainer, but that is another topic.
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
I got 2 same classes, one for the primary weapon and the other for the secondary one. Here are my classes :
public class weapon : MonoBehaviour {
public string Name { get; set; }
public float Damages { get; set; }
public float FireRate { get; set; }
public float Range { get; set; }
public float BulletSpeed { get; set; }
public bool isOn { get; set; }
public weapon(string name, float damages, float fireRate, float range, float bulletSpeed, bool ison) {
this.Name = name;
this.Damages = damages;
this.FireRate = fireRate;
this.Range = range;
this.BulletSpeed = bulletSpeed;
this.isOn = ison;
}
}
public class weapon1 : MonoBehaviour {
public string Name { get; set; }
public float Damages { get; set; }
public float FireRate { get; set; }
public float Range { get; set; }
public float BulletSpeed { get; set; }
public bool isOn { get; set; }
public weapon1(string name, float damages, float fireRate, float range, float bulletSpeed, bool ison) {
this.Name = name;
this.Damages = damages;
this.FireRate = fireRate;
this.Range = range;
this.BulletSpeed = bulletSpeed;
this.isOn = ison;
}
}
I want in another script that when I press 'F', the weapons take respectively their specs, but it gets stuck at giving the name to the second one, here is my script to give them their specs:
void Update () {
if (Input.GetKeyDown (KeyCode.F)) {
GetComponent<weapon> ().Name = "Rien";
GetComponent<weapon> ().Damages = 0;
GetComponent<weapon> ().FireRate = 0;
GetComponent<weapon> ().Range = 0;
GetComponent<weapon> ().BulletSpeed = 0;
GetComponent<weapon> ().isOn = true;
Debug.Log (GetComponent<weapon> ().Name);
GetComponent<weapon1> ().Name = "Rien1"; //stuck here... :'(
GetComponent<weapon1> ().Damages = 0;
GetComponent<weapon1> ().FireRate = 0;
GetComponent<weapon1> ().Range = 0;
GetComponent<weapon1> ().BulletSpeed = 0;
GetComponent<weapon1> ().isOn = false;
Debug.Log(GetComponent<weapon1> ().Name);
}
}
I'm getting 'Object reference not set to an instance of an object' and I did exactly the same thing for both weapons
Thanks in advance
You are making some basic programming errors as well as some basic Unity specific errors. As said in the comments, you shouldn't have lots of classes that are exactly the same. Remember to not repeat your self.
Then you are inheriting from MonoBehaviour but are defining a constructor method to set your fields. Don't do this in unity. Make the feilds available in the inspector by making them public or adding the [SerializeField] attribute to private member variables. If you have anything you want to do when the object is created then put this in the Start() method:
public Weapon : MonoBehviour
{
public string name; //set these in the inspector for each weapon
public float damage;
//etc
// in Unity you use the Start method for mono behaviours. NOT the constructor method
void Start()
{
//Do things when the object is created
}
}
Now, it's not clear how you are adding weapons to your player from your question but what you should do is add a game object as a child to the player object in the hierarchy. Do this for each weapon and then add your weapon script to each weapon. Then change the fields that you made available to yourself in the inspector. You can then get a reference to the weapons that the player currently has via a script on the player and do as you please with their values when you press a key.