Hi guys, im trying to instantiate a sword in my player hand, it works fine but is not a child of my playerhand parent, can anyone help plz? this is the code
using UnityEngine;
using System.Collections;
public class PlayerWeaponController : MonoBehaviour
{
public GameObject playerHand;
public GameObject EquippedWeapon{ get; set;}
IWeapon equippedWeapon;
CharacterStats characterStats;
void Start()
{
characterStats = GetComponent<CharacterStats> ();
}
public void EquipWeapon(Item itemToEquip)
{
if (EquippedWeapon != null)
{
characterStats.RemoveStatBonus (EquippedWeapon.GetComponent<IWeapon>().Stats);
Destroy (playerHand.transform.GetChild (0).gameObject);
}
EquippedWeapon = (GameObject)Instantiate (Resources.Load<GameObject>("Weapons/" + itemToEquip.ObjectSlug),
playerHand.transform.position, playerHand.transform.rotation);
equippedWeapon = EquippedWeapon.GetComponent<IWeapon> ();
equippedWeapon.Stats = itemToEquip.Stats;
EquippedWeapon.transform.SetParent (playerHand.transform);
characterStats.AddStatBonus (itemToEquip.Stats);
Debug.Log(equippedWeapon.Stats[0].GetCalculatedStatValue());
}
public void PerformWeaponAttack()
{
equippedWeapon.PerformAttack ();
}
}
You may find it easier to have all the weapons pre-parented in the editor, starting deactivated, and then activate or deactivate them as necessary. That way you dont have to worry about position, rotation, or creating and destroying on the fly.
What do you observe happening? Does the weapon get parented to anything?
That forces the child to use its local position/orientation only, and ignore where it happened to be in the world immediately before parenting. Personally, I find that you almost always want to pass false to SetParent(), at least when creating new objects. But when taking something that already exists and making it a child of an object, it might be appropriate to pass SetParent() a true second parameter (which is the default when you specify no second parameter).
Are you getting any errors? Try using Debug.Log to print out the object names to make sure the parenting is happening correctly. Is there any other code handling parenting or potentially destroying the parent or setting it to null?
Dont work too⌠i m getting an error yes, but its about the weapon stats that i couldnt find the problem yet too⌠but nothing to be with the instantiation i guess. and this only weapon when i change my cube model from a real model⌠then i try back to cube model but never work properly again.
Yes in line 12⌠damm every single time i try restart my prototype test i get all kinds of problems 1st the click to move interfere with all kinds of stuff, then animations and even this simple this⌠im to newbie yet but this get me frustrated some timeâŚ
Donât get frustrated, you will always run into roadblocks. Itâs just the way it is when learning something new. Think of this as an opportunity to improve your debugging skills, as well as learn a thing or two to avoid this in the future.
So this line is the culprit:
equippedWeapon.Stats = itemToEquip.Stats;
That means that something here is null. Letâs find out what is null.
Now im feeling like a dumb -.- i bet i dont attach the iweapon script to it.
Exaclty i dont have sword script in the weapon but now i get that new iweapon component has no stats in debug⌠but i dont get the error now on line 18 of this script
using UnityEngine;
using System.Collections.Generic;
public class CharacterStats : MonoBehaviour
{
public List<BaseStats> stats = new List<BaseStats>();
void Start()
{
stats.Add (new BaseStats(4, "Strenght", "Your attack power."));
stats.Add (new BaseStats(2, "Vitality", "Your vitality level."));
}
public void AddStatBonus(List<BaseStats> statBonuses)
{
foreach(BaseStats statBonus in statBonuses)
{
stats.Find (x => x.StatName == statBonus.StatName).AddStatBonus (new StatsBonus (statBonus.BaseValue));
}
}
public void RemoveStatBonus(List<BaseStats> statBonuses)
{
foreach(BaseStats statBonus in statBonuses)
{
stats.Find (x=> x.StatName == statBonus.StatName).RemoveStatBonus(new StatsBonus(statBonus.BaseValue));
}
}
}
And i hv this 2 more scripts
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class BaseStats : MonoBehaviour
{
public List<StatsBonus> BaseAdditives { get; set; }
public int BaseValue { get; set; }
public string StatName { get; set; }
public string StatDescription { get; set; }
public int FinalValue { get; set; }
public BaseStats(int baseValue, string statName, string statDescription)
{
this.BaseAdditives = new List<StatsBonus> ();
this.BaseValue = baseValue;
this.StatName = statName;
this.StatDescription = statDescription;
}
public void AddStatBonus(StatsBonus statBonus)
{
this.BaseAdditives.Add (statBonus);
}
public void RemoveStatBonus(StatsBonus statBonus)
{
this.BaseAdditives.Remove (BaseAdditives.Find(x => x.BonusValue == statBonus.BonusValue ));
}
public int GetCalculatedStatValue()
{
this.FinalValue = 0;
this.BaseAdditives.ForEach (x => this.FinalValue += x.BonusValue);
this.FinalValue += BaseValue;
return FinalValue;
}
}
using UnityEngine;
using System.Collections;
public class StatsBonus
{
public int BonusValue { get; set; }
public StatsBonus(int bonusValue)
{
this.BonusValue = bonusValue;
Debug.Log ("New stat bonus initiated.");
}
}
Try not to focus on the end result, just focus on fixing each error one at a time. Itâs possible that fixing one error will fix others as well.
So you say that youâre seeing ânew IWeapon component has no statsâ in the log now. Thatâs okay, because that is printing out before you assign the stats so it must be null. That also means youâre getting past the previous Debug statement, so IWeapon is no longer null.
Yes, that is called the stack trace, and those 3 scripts are which bits of code were run before the error happened. Theyâre clues to help you track down the bug.
The actual object that is null is on line 18 of CharacterStats.cs. PlayerWeaponController on line 51 makes a call to CharacterStats, and InventoryController on line 23 calls to PlayerWeaponController.
Line 18 of CharacterStats.cs is this:
stats.Find (x => x.StatName == statBonus.StatName).AddStatBonus (new StatsBonus (statBonus.BaseValue));
So just like before, lets change the function to catch what is really null and where itâs coming from:
Try this:
public void AddStatBonus(List<BaseStats> statBonuses) {
if(statBonuses == null) {
Debug.Log("CharacterStats -> AddStatBonus: parameter list null");
return;
}
if(this.stats == null) {
Debug.Log("CharacterStats: class variable 'stats' is null");
return;
}
foreach(BaseStats statBonus in statBonuses) {
stats.Find(x => x.StatName == statBonus.StatName).AddStatBonus(new StatsBonus(statBonus.BaseValue));
}
}
Itâs possible that PlayerWeaponController is passing null into âAddStatBonusâ. I havenât seen your PlayerWeaponController, but itâs also possible that InventoryController is passing null to PlayerWeaponController.
So follow those breadcrumbs and track down what is null and why.
i just dont get where is the error in that lineâŚ
and i get this debug: a stat within statBonuses list is null but i think its normal cuz we just add the stats after right? or thats the error? cuz now i get debugg the value of 6 (the stats i add in start function)