how would you change the character controller height in unity using code? - c#

i tried googling this bs but couldnt find out how to do it

According to the Unity Scripting Reference, you can directly access and set the height property on the CharacterController class.
Start by gaining a reference to your CharacterController in your script
This can be done in two ways:
Start by defining a CharacterController variable in your script. You can either expose the variable in the Unity editor by using [SerializeField] or you can find the component by using GetComponent.
[SerializeField] private CharacterController controller;
or
private CharacterController controller;
void Start(){
controller = GetComponent<CharacterController>();
}
Once you have access to your CharacterController component, you can access the height property on it in your code. Here is an example on how you could do this to make a simple crouch mechanic
using UnityEngine;
public class Example : MonoBehaviour
{
private CharacterController controller;
void Start()
{
controller = GetComponent<CharacterController>();
//Set height to 2 at the start of the game
controller.height = 2.0f;
}
void Update()
{
if(Input.GetKeyDown(KeyCode.LeftShift)){
//Set the height to 1.5 if the left shift key is pressed
controller.height = 1.5f;
}
else if(Input.GetKeyUp(KeyCode.LeftShift)){
//Set the height to 2.0 when the user releases shift
controller.height = 2.0f;
}
}
}
For future reference, the Unity Documentation is a great resource for figuring out what properties and functions are available on components.
You can find the Unity scripting documentation HERE.

Related

I can't assign script from another object. Is there smth wrong?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MeteorRangeController : MonoBehaviour
{
[SerializeField] PlayerController PlayerController; // It has to be script
[SerializeField] GameObject Player; // no problem with assigning this
[SerializeField] Transform playerTransform;
[SerializeField] Vector3 playerPos;
[SerializeField] bool canGo;
[SerializeField] GameObject meteor;
// Start is called before the first frame update
void Start()
{
playerTransform = Player.GetComponent<Transform>();
PlayerController= Player.GetComponent<PlayerController>(); //*The Problem Is Here*
//PlayerController Cannot Be Assigned
}
// Update is called once per frame
void Update()
{
print(PlayerController.IdleTime); //to test it I printed
playerPos = Player.transform.position;
//I tried to take idle time from Player controller here.
if (PlayerController.IdleTime > 2)
{
canGo = true;
}
else
{
canGo = false;
}
if (canGo == true)
{
transform.position = new Vector3(playerPos.x, playerPos.y, playerPos.z);
gameObject.SetActive(true);
Invoke("SetActiveFalse",2f);
}
}
void SetActiveFalse()
{
gameObject.SetActive(false);
meteor.SetActive(true);
Invoke("MeteorSetActiveFalse", 2f);
}
void MeteorSetActiveFalse()
{
meteor.SetActive(false);
}
}
I can't assign it.
I researched it but I couldn't find anything different.
I know it's a very easy question, also I assigned game object player, in it there is a script named PlayerController, and there is a variable named idle time please help me
Okay, that's my first try to answer on topic on Stack Overflow, so hope you will be patient to my mistakes.
Can you say, are you sure, that Player object has a PlayerController script on him?
I think you must use
var isControlSetted = Player.TryGetComponent<PlayerController>(out PlayerController);
instead of:
PlayerController= Player.GetComponent<PlayerController>();
Why? So, that can answer on question №1 and after it you can control the logic of working with it when (use AddComponent for example or throw an exception)
3. Okay, even that can't fix your problem if PlayerController setted on inheritor or ancestor of Player gameobject in gameobject hierarchy
I hope I helped you
Edited:
Okay, I was asked to make answer some clearly, so...
First of all, can you show PlayerController script, pls?
Secondary, why I'm asking to use TryGetComponent instead of GetComponent bcs as I commented below getting null value is not a good practice, but if you want - use it.
Let's look on script more closly
I refactored this pls look
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MeteorRangeController
: MonoBehaviour
{
[SerializeField] PlayerController playerController;
[SerializeField] GameObject playerObject;
[SerializeField] Transform playerTransform;
// [SerializeField] Vector3 playerPos; we don't need this
// [SerializeField] bool canGo; and this
[SerializeField] GameObject meteorObject;
/// <summary>
/// Method that called once we use this or Awake for init our fields/props
/// </summary>
void Start()
{
playerTransform = playerObject.GetComponent<Transform>(); // there no need to use TryGetComponent bcs Transform is req. for every GO/MB
playerController= playerObject.GetComponent<PlayerController>(); // there you could use TryGC, but if you use RequireComponentAttribute that's ok
}
/// <summary>
/// Method that's calls every frame
/// </summary>
void Update()
{
if (playerController.IdleTime <= 2)
return;
transform.position = playerTransform.position;// i really can't understand what hepenning after this so i stop
gameObject.SetActive(true);
Invoke(nameof(SetActiveFalse),2f);
}
void SetActiveFalse()
{
gameObject.SetActive(false);
meteorObject.SetActive(true);
Invoke(nameof(MeteorSetActiveFalse), 2f);
}
void MeteorSetActiveFalse()
{
meteorObject.SetActive(false);
}
}
So, afterwards GO.GetComponent can return null only if the requested GO did not have a Monobehaviour script.
You can check similar question there https://forum.unity.com/threads/getcomponent-doesnt-works.516839/

How do i add the objects that the raycast is hitting in unity and add them to a list

I have this problem that i just can't figure out how to solve.
I am trying to make a game in Unity, and i have stumbled across a problem that goes like this.
I want to put an object in the scene in a list, when i hit it with a raycast.
With what i have tried so far. Either it puts everything that is tagged the same thing on the list when i press mousebutton on one of the objects, or it only puts in the same thing (Cube in this example).
My code is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerTagged : MonoBehaviour
{
public float damage = 10f;
public float range = 100f;
public Camera fpsCam;
public List<GameObject> playersTagged;
private void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Shoot();
}
}
void Shoot()
{
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Target target = hit.transform.GetComponent<Target>();
if (target != null)
{
target.takeDamage(damage);
if(hit.collider.tag == "Taggable")
playersTagged.Add(GameObject.FindWithTag("Taggable"));
}
}
}
}
use
playersTagged.Add(hit.collider.gameObject);
Instead of using GameObject.FindWithTag() which returns the first object it'll find source
Use gameobject property playersTagged.Add(target.gameobject). Since all components store the reference to the gameobject they are attached to.
You are adding GameObject.FindWithTag("Taggable") which means you are getting any GameObject that has that tag and adding it to the list. But instead, you want to add the hit object, so you need to add hit.collider.gameObject.

I dont get why unity gives a compile error here

I'm trying to change the text of a TMPro text box, but unity reports at 20,79 I need a }. I put in the bracket and 11 errors pop up. debug pls? I don't know much c# myself so I can't do it myself. pls, help.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class tetxmeshpro : MonoBehaviour
{ int previoushealth = 100;
private TextMeshProUGUI textMesH;
// Start is called before the first frame update
void Start()
{
var Player; GameObject;
textMesH = GetComponent<TextMeshProGUI> ();
}
// Update is called once per frame
void Update()
{
if ((Player.GetComponent(playerScript).Health)) not == previoushealth;)
{
previoushealth = Player.GetComponent(playerScript).Health;
textMesH = previoushealth;
}
}
}
What exactly is
var Player; GameObject;
supposed to do? ;)
It seems you rather mean
GameObject Player;
Either way the Player is not a field so later in Update you don't have access to it either. You probably rather wanted a
[SerializeField] private GameObject Player;
on class level so you can reference your object in it. Or even better give it the correct type right away:
[SerializeField] private playerscript player;
This way you don't need the GetComponent later.
What is this
if ((Player.GetComponent(playerScript).Health)) not == previoushealth;)
This is c# not some Shell/Dos script -> use != and not not ==. Also if conditions don't end with a ; and there is a ) too much. And also GetComponent either is generic, then it is GetComponent<T>() or you pass in a type but then you have to cast it like ((T)GetComponent(typeof(T))).
If something it should rather simply be
if (Player.GetComponent<playerScript>().Health != previoushealth)
Your class should rather look like
public class tetxmeshpro : MonoBehaviour
{
int previoushealth = 100;
// Link these via the Inspector using drag&drop
[SerializeField] private TextMeshProUGUI _textMesH;
[SerializeField] private playerscript _player;
// Start is called before the first frame update
private void Start()
{
if(!_textMesH) _textMesH = GetComponent<TextMeshProGUI>();
}
private void Update()
{
if (_player.Health != previoushealth)
{
previoushealth = _player.Health;
textMesH = previoushealth;
}
}
}
Though, note that naming your class textmeshpro a) might lead to confusions with the existing TextMeshPro and also doesn't at all reflect the purpose of that class. I would suggest something like e.g. HealthDisplay or anything similar meaningful.

How can I reference a game object on my scene in a prefab component I have just instantiated?

Currently I am learning both Unity and C#. I am working on a small game where I control a spaceship on the screen, while meteors are spawning in a random position outside of the camera's visible space, then start to move towards the ship.
For this I am trying to refer to the ship game object in a component on a meteor prefab, to get it's position and the angle needed to start moving towards the ship.
public class meteorPath : MonoBehaviour
{
public float speed = 10f;
public Rigidbody2D rb;
public GameObject ship;
void Start()
{
int typeOf = Random.Range(2, 11);
Vector3 posOf = new Vector3(Random.Range(-7f, 7f), Random.Range(16f, 8f), 0);
transform.localScale = new Vector3(typeOf, typeOf, 1);
transform.localPosition = posOf;
}
}
How can I make get the player's position to calculate the angle needed every time I instantiate a meteor?
I'm guessing that you're instantiating everything at runtime.
You would either do:
GameObject.Find(YOUR OBJECT NAME)
GameObject.FindGameObjectWithTag(sometag), only if your player has a tag
Make player's class singleton and reference it from other classes with PlayerClassName.InstanceName and reference the position.
If you're not instantiating everything but is a static scene, then just make a prefab of the meteor with the player's reference inside
one way to get references is to create instanced game manager:
and when meteor is created you have it get player position from that instanced GameManager.
in start of meteor:
private Vector3 playerPosition = GameManager.instance.playerPosition.transform.position;
in GameManager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager instance;
public GameObject playerPosition;
private void Awake()
{
instance = this;
}

Input.GetMouseButtonUp not working as expected in Unity

I have a 2D Unity game with numerous agents that can be selected when they are clicked on. When this happens they become the player (the player's agent variable is replaced with them and the agent becomes the player's parent). I am trying to implement a system where you drag their destination over another agent to "Target" them.
To do this I am actually targeting from within the target's My class (a class that holds references to all the player's components and variables) so I am putting the agent into a function that is operated by the player's current agent. This seems to work in theory, but in Unity it is only allowing me to target the first agent in the hierarchy, and none of the others. But all the agents are identical instances of the agent prefab, generated at the start of the game.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Agent : Grammar {
public Physical physical;
public Agent agent;
void Update() {
float distanceFromMouse = the.Distance(this.transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition));
if (Input.GetMouseButtonDown(0)) {
if (distanceFromMouse < 1f) {
the.player.agent = this;
the.player.transform.parent = this.transform;
}
}
if (Input.GetMouseButtonUp (0)) {
if (distanceFromMouse < 1f) {
if (the.player.agent != this && the.player.agent is Agent) {
the.player.agent.Target (agent);
}
}
the.player.agent = null;
}
if (the.player.agent == agent)
physical.goal = Camera.main.ScreenToWorldPoint (Input.mousePosition);
else if (physical.hasTarget)
physical.goal = physical.target.transform.position;
}
}
public void Target (My target) {
my.physical.target = target;
my.physical.hasTarget = true;
foreach (My other in the.agents.GetComponentsInChildren<My>()) {
if (other.physical.targetters.Contains (my))
other.physical.targetters.Remove (my);
}
target.physical.targetters.Add (my);
target.physical.targetted = true;
}
Here is my Grammar class that everything inherits from so they can access the global The class.
using UnityEngine;
using System.Collections;
public class Grammar : MonoBehaviour {
public A a;
public The the;
}
Here is my The (global utility) class
using UnityEngine;
using System.Collections;
public class The : MonoBehaviour {
public Grid grid;
public GameObject world;
public Player player;
public GameObject squareParent;
public GameObject linkParent;
public GameObject nodeParent;
public GameObject agents;
public Vector2 HeadingFrom(float angle) { return new Vector2(Mathf.Cos(angle * Mathf.Deg2Rad), Mathf.Sin(angle * Mathf.Deg2Rad)); }
public float AngleFrom(Vector2 heading) { return Mathf.Atan2 (heading.y, heading.x) * Mathf.Rad2Deg; }
public Vector2 RelativeHeadingFrom(Vector2 heading, float rotation) { return (Vector2)(HeadingFrom(AngleFrom(heading) - rotation)); }
public float Distance(Vector2 from, Vector2 to) { return (Heading(from,to)).magnitude; }
public Vector2 Heading (Vector2 from, Vector2 to) { return to - from; }
public Vector2 MidPoint (GameObject my, GameObject their) { return (my.transform.position + their.transform.position) / 2; }
}
The way you are detecting the clicks in your agent class is a bit off. While the property Input.mousePosition returns a Vector3 the Z component is always zero. The documentation for the Camera.ScreenToWorldPoint function notes that the Z component of the supplied vector is the distance in world-units from the camera, this means that the world-position of your "clicks" in the Agent class will always be right next to the camera.
The usual approach is to either define the methods OnMouseDown() and OnMouseUp() (in your Agent class) or use Camera.ScreenPointToRayto create a Ray which is then used to do a raycast into the scene and then using the ray hit-result as the 'actual world' position of the mouse pointer. See this answer on Unity Answers for more about that.
I suggest you use the new event system (which is part of the new Unity GUI system) to detect if an agent has been clicked instead as this also handles touch input in case you want to your game to work on a mobile device.
What you would need to do to do that is:
Implement the interface IPointerUpHandler and IPointerDownHandler in your agent class and handle the clicks in the methods the interfaces require you to define.
Make sure you have some kind of collider (or trigger) on your agent.
Make sure you add a PhysicsRaycaster component on your Camera object.
You might also be interested in these interfaces:
IBeginDragHandler
IDragHandler
IEndDragHandler
IDropHandler

Categories

Resources