For a 2D sidescrolling platformer, i've made a little gear system here is the description :
Player (My main player gameObject with Gear script attached)
Gear (This gameObject is just for organization, it's named "root" in the script, and has no script attached)
Armor (the armor with sprite and Armor script)
Weapon (the weapon with sprite and Weapon script)
I have a script attached to Player which is Gear, with a reference to "Gear" GameObject to use it as parent transform for my future items.
In gear, I equip a weapon this way :
public void Equip(Wearable w){
switch (w.type) {
case Wearable.Type.WEAPON:
GameObject weaponGO = Instantiate(w.gameObject);
weaponGO.transform.SetParent(root.transform);
Destroy (this.weapon.gameObject);
this.weapon = w.GetComponent<Weapon>();
break;
//I did a swicth because i'll do it for armor, pets etc afterwards
}
}
The problem is that I also have an animator on the payer, to attack, move, etc...
SO when i change my weapon, it spawns at 0,0,0 and it's not following animations at all, and in my player's animations, I see"Weapon : Position (Missing !)", so i think this comes from animation references... But how to change this in my script?
The problem seems to be in the object naming. So after the instantiation you have to rename the new weapon object so that it's name would be exactly the same as the one you've deleted. The reference in the animator should update automatically after that.
Note that the position in the hierarchy should also be the same relative to the object with the Animator component.
Also note that the instantiated object should have the same properties (Components) used in Animator as the deleted one.
Related
I made a trigger where the player collides and it goes to the main menu (scene 0) and it just wont work. I'm using unity with c#:
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneTransition : MonoBehaviour
{
public string SceneToLoad;
public void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Player")) ;
{
SceneManager.LoadScene(SceneToLoad);
}
}
}
`
There is very little detail in your question. Please check the following:
1. Is the collider attached to both the player and the trigger object?
2. What are their settings? Kinematic,etc ?
3. do you have a RigidBody attached to the player or the trigger object?
4. Is the SceneToLoad already registered in the Build?
These are the basics to make what you want. I suggest you revise the following topics:
1. Collision, Colliders and Rigidbody, especially search for Collision matrix
2. How SceneManagement works
Is your game 3D or 2D? If its 3D, change the OnTriggerEnter2D to JUST OnTriggerEnter().
And check that the Is Trigger in the box collider (or whatever collider you're using) is checked. :)
You also put in a semicolon in the if(other...) so remove that. Semicolons aren't supposed to be put in to if statements
Obligatory "i'm very new". I couldn't figure out how to hook up a canvas that the player interacts with (chooses which team they'll be playing on in the game) that I had would work out if it was in the scene that the player prefab would be spawned into. So I put the canvas into the prefab with the player and set it as inactive once they select which team.
It works flawlessly for the host client (changes their "playerTeam" int and spawns them where they should be spawned) but when the second client joins their canvas is there, but won't take any input. I know it's this because the debug.log i put in right after input is not being run. here are the code segments that are necessary.
i have the canvas disabled by default and activated after an (isLocalPlayer) run on a script on the parent object. I can't add a networkID to the canvas because the prefab parent object has the networkID and they both can't have one, which means I cannot use (isLocalPlayer) on the canvas script, which may be the issue. But I also can't have the canvas on the actual level screen because even if i find the game object of the canvas, i don't know how to make it find which player to assign the playerTeam int to.
The following is run on a script attached to the canvas (of which the empty player object is the parent of)
Button CT = chooseCT.GetComponent<Button>();
CT.onClick.AddListener(parent.GetComponent<Sync>().CmdpickedCT);
and this is the code that runs on a script on the parent object
[Command]
public void CmdpickedCT()
{
GetComponent<Movement>().playerTeam = 2;
teamSelector.SetActive(false);
}
I apologize if I'm missing something big here. Thanks for any help.
for more information i have more stuff in the movement script run once the playerTeam is set to something other than 0, this also works on the host. Any other information you can give about how to pass info from the objects in the game scene to the instantiated objects would be great too. Thanks again.
Additional information, it seems like if i have both the second client and first client on the canvas at the same time, I cannot choose my team with either. It says "Trying to send command for object without authority".
I'm debugging a MonoBehaviour script in MonoDevelop.
There is a way to select (in the Unity Editor) the gameobject the current paused script is attached to?
(I have multiple instances of the same prefab with that script attached, so finding it in the Hierarchy is not trivial)
You can do this fairly easily by taking advantage of Unity's Selection class. Just be sure to add using UnityEditor; at the top of your script.
To select the gameObject you are debugging in your hierarchy, simply set the Selection.activeGameObject property in your script right after the line you are placing your break point on. For example:
void Update()
{
int breakPoint = 5; //your breakpoint is placed here
//select this gameObject in the hierarchy
Selection.activeGameObject = this.gameObject;
}
Basically, what I want to do is have two objects (fpscontroller and a wall) that collide like normal. But, once a script runs, they won't collide anymore.
So, how do I make that script that makes the two objects ignore collision with each other? I've tried looking this up, and what I got was Physics.IgnoreCollision, but the documentation on that confused me. And when I tried putting it in and replacing their variables with my variables, I got a bunch of errors.
So, please help.
The way i would go about doing this is through layers.
In unity, a convenient way to ignore physics collision between objects is through setting the object to be ignored to a layer which your player object will always ignore.
So, to go about setting this up imagine the following:
fpscontroller's layer is set to "player" (a layer i have created and named such).
wall's layer is initially always set to "wall" (once again a layer i have created)
Additionally, I create a layer that i call "IgnorePlayerCollisions"
Now i go to: Edit > Project Settings > Physics
Here i can check the box which will turn off collisions between my player and IgnorePlayerCollisions layers.
Now, at runtime i run my script which says:
Change Wall Layer to "IgnorePlayerCollisions". Voila, my player now ignores all collisions with this layer.
Code Examples: (You don't need these all):
// Function to Change a GameObject Layer to the Ignore Layer
public void ChangeGameObjectLayerToIgnore(GameObject go) {
go.layer = [Index of Ignore Layer];
}
// Function to Change "This" GameObjects layer to any other layer
public void ChangeThisGameObjectLayer(int layerIndex) {
this.gameObject.layer = layerIndex;
}
// Change a GameObject layer to another layer
public void ChangeGameObjectLayer(GameObject go, int layerIndex) {
go.layer = layerIndex;
}
How?
Place a C# function into a script and attach it to either your desired gameobject. In your case, i may attach it my Player GameObject since it seems like you may want to disable object throughout the game based on specific trigger or something. It really depends on how you plan to trigger the function.
Let me know if this makes sense or not. If not, i can attempt to make it more legible.
Good luck and have fun!
I just learned how easy it is to simply drag a 3rd person character controller prefab (from Unity's standard assets package) and drop it into the hierarchy.
Using the WSAD and Space keys feels pretty natural, so I wondered if I could apply the same character controller to a customized avatar.
Using the free AutoDesk Character Generator (https://charactergenerator.autodesk.com/) I created one (fbx file) and imported it into Unity, so now I have my own character prefab.
I, then, searched for the steps to animate it just like a a 3rd person character controller, with the following article coming up first, but I wonder if I always have to do all the steps?
http://blogs.unity3d.com/2014/04/14/turn-your-character-into-a-player/
Once you have a customized character in the form of a Unity prefab, should do still go through all these steps, or is there a simpler way of animating your avatar; e.g. adding the basic necessary scripts?
That article gives a good overview of what is required.
However, you can essentially skip almost all those steps when using autodesk character generator.
Here is a quick way:
Set your FBX to be a mecanim humanoid
Drag an mecanim animator controller onto it
Write your code to set the animator states (eg: speed, jumping, etc)
To do that:
Export from Autodesk as "Unity FBX" format to get YourCharacter_Unity.fbx
Drag the FBX into the unity project files
Click on the YourCharacter_Unity FBX in project (blue cube), select "RIG" tab in inspector, and change Animation type to "Humanoid" (which maps it to the Mecanim system).
Drag the FBX from the project into the scene.
Go to the Asset Store and import "Mecanim Locomotion Starter Kit" (which has a basic locomotion controller and a set of animations)
Drag the "Locomotion Setup/Locomotion/Locomotion.controller" onto the "controller" variable on your character's Animator component.
Untick "apply root motion"
Now, if you hit run you will see your character standing there with idle motions. If you double click on the animator controller on your character it will open up the Mecanim Animtor window and you can manually set the animation state. Try changing the speed to 1.0 and you will see him walk/run.
Note: In your character's Animator component if you checkmark "Apply root motion", then the feet animation will cause your avatar to automatically move when his speed > 0.
You say you are using a CharacterController, so here is a very simple script that references the character controller to get the current speed, and then set the speed on the Animator:
using UnityEngine;
using System.Collections;
public class CharacterAnimator : MonoBehaviour {
public CharacterController controller;
public Animator animator;
private int speedid;
void Start () {
animator = GetComponentInChildren<Animator>();
controller = GetComponent<CharacterController>();
speedid = Animator.StringToHash("Speed");
}
void Update () {
float speed = controller.velocity.magnitude;
animator.SetFloat(speedid, speed);
}
}