So I'm using the unity standard assets pack and I was trying to figure a way to freeze the players location, at first I tried to freeze the players location using the rigidbody but the character was still able to walk. Next I tried to disable the script that allows the player to move but I cannot see the script is other scripts (when I use public script name variable name it doesn't show up as a script name.
Since I can’t see the script, I don’t have much to go off of, but I’m assuming you’re using some either Input.Horizontal and Input.Vertical, or Input.getKey() to do your things.
If you want to freeze the movement, you can simply wrap the function for movement that you are using in an if statement with some kind of bool that contains whether or not the player should be frozen.
Example:
If(!frozen){
Player.Position.x += 5;
}
Or something like that.
If you need to get the variable in another script you could do something like this (this is a rough example to try to explain it, syntax may not be perfect):
GameObject player;
Player.MoveScript.frozen = false;
Something like that.
Related
Maybe im missing something obvious but to keep it short. I have working code for a character. When you "dash" I want to leave behind an after-image type effect, by cloning the player, removing its unneeded components and then applying a shader. Issue is as soon as I instantiate the clone the original player stops functioning (cant move etc). It still has all its components and everything as normal, and the clone does get the correct components removed. But it still breaks. As soon as I remove that line, its back to normal. Any ideas?
This is the only relevant code in the script that instantiates the clone.
private void DodgeEffect()
{
GameObject _DodgeSFX = Instantiate(gameObject, transform.position, transform.rotation );
Destroy(_DodgeSFX.GetComponent<PlayerController>());
Destroy(_DodgeSFX.GetComponent<PlayerCombat>());
Destroy(_DodgeSFX.GetComponent<WarpController>());
Destroy(_DodgeSFX.GetComponent<Animator>());
}
its because you are making a copy of gameObject. while Instantiate() returns a GameObject, it also returns whatever you put into the first section of the method. instead, make a seperate gameObject than the player in the editor, and make _DodgeSFX public so you can put the copy into the slot. Then, just instantiate that seperate GameObject and you wont have to destroy the components through script(because you remove the components in the editor), saving time
Ok so from some testing I think its down to the Unity.InputSystem only allowing 1 instance of each Input to be enabled at once. When I instantiated a clone of the player, it still goes through the Enable/Awake functions before those components are destroyed, and since the Inputs on that clone were never disabled, that becomes the "main" one. If I set the main player's scripts with Inputs deactive and then active again, it all works as normal. Note that the script was still working on the main character just fine, it was only the inputs that was broken. Im still not sure why this is the case, if its a limitation of the input system, or intentional, cant seem to find documentation of this experience anywhere.
I'm currently developing a game in Unity using C# and I've run into a small problem.
I need to spawn a certain gameobjects relative to the Spawnposition and length of another game object. Now I figured that bounds.size would be the best function to use in this instance. As shown bellow I declare first the variable that uses this in my start method:
public void Start()
{
GameObject PointBar = (GameObject) Resources.Load("PointBar Horizontal");
PointBarVectorLength = PointBar.GetComponent<BoxCollider2D>().bounds.size.x;
PointBarVectorConv = Camera.main.WorldToViewportPoint(new Vector2(PointBarVectorLength, 0f));
}
However, the gameobjects in question are inactive at start's call and thus I presume don't return any value for bounds.size when called.
Does anyone know how I can access the bounds.size or equivalent of an inactive gameobject or is there something else I'm missing here?
As noted in the documentation for the Collider.bounds property, bounds "will be an empty bounding box if the collider is disabled or the game object is inactive". So your assumption was pretty much right. Since the object doesn't exist in worldspace that makes sense.
I'm not sure about the most elegant solution for your use case but two options spring to mind.
Calculate the object's spawn dimensions by accessing its transform.localScale and factoring in the scale of prospective parent objects. That could get messy but you could probably also write a helper method to make it more manageable.
Instantiate the object somewhere off screen after you load it, access its Collider.bounds property to get the information you need then move it where ever you want it or store the information for later.
There may be better solutions but that's what leaps to mind for me.
I solved the issue by using GetComponent().bounds.size.x;
instead of BoxCollider. This component can get accessed when the game object is not active.
I am making my first game in Unity and I'm trying to load the first level of it when the cutscene at the start ends. I don't know if it's possible to make the script do something after a video clip ends, so I wrote my code like this:
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class CutsceneEnd : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
StartCoroutine("wait");
}
IEnumerator wait()
{
yield return new WaitForSeconds(36);
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
}
}
But the problem is not with my method of waiting for the end of the video, it's with the scene it loads. I can't move my character because all the references in the scripts are null. I have no idea what I did wrong.
Unity references should be stored in the scene file. Are you using any source control like git? If someone else did not push the changes to the .unityscene file or the .meta files for the associated scripts/prefabs, it might break the references.
I think we need some more information here.
If you referring to references (public variables) to Assets/GameObjects in the loaded scene, then you may have simply never placed the references in the first place. Unity's public variables should be saved within the Scene file and should always load with the Scene.
Double check to see if the references are actually null. Are you using an animation when you load into the Scene? This can keep you from being able to manual move anything. For example, if you animate the character when loading the scene, it could get stuck in the animation clip and you won't be able to move it.
Lastly, if you are referring to references created within the code to other scripts, objects, or variables, then these may break between scenes if you don't utilize 'DontDestroyOnLoad'.
Just spit-balling here, I need more information to correctly find the solution.
i'm making my first enemy AI in unity. I'm trying to make a finished state machine with the animator controller to do it.
I just discovered the StateMachineBehaviour script which is called when the AI is in a state. It has multiple methods, including the OnStateEnter. It is called everytime the AI enter the state.
My problem is only about optimization, my AI need to get the GameObject "Player" in order to attack it. So i'm getting it in my OnStateEnter method for the moment, which i feel is bad, because i'm getting it every time the animation is called, i would like to get it only once, at the start.
I basicly need a start function but it's not working, i have made research and found nothing. I tried to watch video about people making a finished state machine but they are just getting the same GameObject multiple time ( example here : https://youtu.be/dYi-i83sq5g?t=409 ).
So, is there a way to have a start function or to get an element only once ?
I could make a bool that is called only the first time and that get the GameObject, but again that would be an "useless" if running in my function.
Any suggestions ? Thanks
No, unlike a MonoBehaviour a StateMachineBehaviour has no Start message only OnStateEnter, OnStateExit, OnStateIK, OnStateMove and OnStateUpdate.
There are also Awake and OnEnable but I'm pretty sure they are not used in the StateMachine and might not behave as expected.
You can however either use
OnStateMachineEnter
Called on the first Update frame when making a transition to a StateMachine. This is not called when making a transition into a StateMachine sub-state.
Or use a simple bool flag like
bool alreadyExecuted = false;
OnStateEnter()
{
if(alreadyExecuted) return;
// Do your stuff
alreadyExecuted = true;
}
(Just a guess)
In the Inspector you actually can enable and disable StateMachineBehaviours like components. So it might be able to do this also in script maybe the same way using
enabled = false;
but I didn't find anything about it in the API and since I'm currently on my Smartphone I can't test it.
I am just about to tackle a new project where the core game mechanic is covering up dead bodies killed by the mafia with leaves using a leafblower.
You need to cover them well enough to not draw attention when the police question you.
The only problem I can see with this project is how to create this leafblower mechanic.
Off the top of my head I can think of attaching an empty object to my leaf blower which has a constant [rigibody.AddExplosiveForce] that procs on mouse click but thats it.
What should I be looking at and what would be a logical way to create this? You do not need to write the whole code for me, I just wan't to know what tools or scripting API I need to consider.
Thank you :)
You could try continuous adding force using Rigidbody.AddForceAtPosition(). Or calculate directions and try Rigidbody.AddForce().
Basically Rigidbody.AddExplosionForce is working as Rigidbody.AddForce, but uses sphere to calculate Vector3. If you need to emit it continuously, you should just use it in FixedUpdate() and list of object you can get by using Raycasts or simple Trigger Collider, for example Capsule Collider.
You could use Collider Capsule like this ↑↑↑. And in OnTriggerEnter or OnCollisionEnter:
private void OnCollisionEnter(Collider other) {
if (other.gameobject.tag != "leaf") return;
// Your AddForce here.
// Also you can get exact point of collsion by using
// other.contacts and use this as AddForce argument.
}