Below is the Code I read somewhere to keep a check on whether the player is on the Ground or Not.
We have to set the LayerMask whatIsGround from the Inspector.
I know the OverlapCircle method creates some kind of Circle but i don't know what exactly doest it do and what does it check.
How does it use the LayerMask to determine whether it's on ground or not.
public LayerMask whatIsground;
public Transform groundCheck;
public float groundCheckRadius;
public bool isGrounded;
isGrounded = Physics2D.OverlapCircle(groundCheck.position,groundCheckRaadius,whatIsground);
Related
how to destroy an object in unity?
I know you have to type the command
Destroy();
but what I'm saying is that I don't know what to put between brackets.
I have tried many different ways:
public GameObject motor;
Destroy(motor);
but it does not work
using System.Collections;
using UnityEngine;
public class LogRotation : MonoBehaviour
{
[System.Serializable] //this will allow us to edit it in the editor
//a custom class representing a single rotation "element" of the log's rotation pattern
private class RotationElement
{
//to get rid of an obnoxious warning about these fields not being initialized
#pragma warning disable 0649
public float Speed;
public float Duration;
#pragma warning restore 0649
}
[SerializeField] //attribute making private fields editable in the Unity Editor
//the aforemention full rotation pattern of the log
private RotationElement[] rotationPattern;
//this will be set to the Wheel Joint 2D from the LogMotor object
private WheelJoint2D wheelJoint;
//something has to actually apply a force to the log through the Wheel Joint 2D
private JointMotor2D motor;
private void Awake()
{
//setting fields
wheelJoint = GetComponent<WheelJoint2D>();
motor = new JointMotor2D();
//starting an infinitely looping coroutine defined below right when this script loads (awakes)
StartCoroutine("PlayRotationPattern");
}
private IEnumerator PlayRotationPattern()
{
int rotationIndex = 0;
//infinite coroutine loop
while (true)
{
//working with physics, executing as if this was running in a FixedUpdate method
yield return new WaitForFixedUpdate();
motor.motorSpeed = rotationPattern[rotationIndex].Speed;
//hard coded 10000, feel free to experiment with other torques if you wish
motor.maxMotorTorque = 10000;
//set the updated motor to be the motor "sitting" on the Wheel Joint 2D
wheelJoint.motor = motor;
//let the motor do its thing for the specified duration
yield return new WaitForSecondsRealtime(rotationPattern[rotationIndex].Duration);
rotationIndex++;
//infinite loop through the rotationPattern
rotationIndex = rotationIndex < rotationPattern.Length ? rotationIndex : 0;
}
}
}
TLDR; Destroy(motor.gameObject), but it will not work if JointMotor2D doesn't inherit MonoBehaviour.
Destroy(obj) can be used to destroy a component too.You need reference it to the game-object to destroy it.
Destroy(GetComponent<RigidBody>()) would remove the RigidBody out of the game-object, rather than removing the object itself.
Destroy(motor.gameObject) should do the trick.
But upon seeing your code, it may not.As it seems like JointMotor2D isn't a MonoBehaviour, aka it doesn't exists in the game-world, hence you can't destroy it.
Depending on what your trying to destroy, you have to find a reference to it.
Simplest way is to reference it in the inspector. Or destroy itself if that is already the object you want to destroy:
// Drag-drop the object in the inspector
[SerializeField]
private GameObject toDestroyLater;
private void DestroyObject() {
Destroy(toDestroyLater);
// Destroys self
// (Aka, whatever game-object this script is attached to)
Destroy(this.gameObject);
}
I have 3(Three) BoxCollider2D components where 2(two) have OnTrigger checked in my Object and both have different functions. Due to having OnTrigger on both, the projectiles I am casting collide with the wrong collider and instead activate that function. Is there a way to ignore 1(one) OnTrigger collider?
I have already tried Layer-based collision detection and set up a layer. Unfortunately, the object now collides with the collider which eliminates the player on collision
However, there are several ways to solve this problem. All kinds of physics.checks as well as raycasts but this code helps you to ignore the obstacle collider.
public Collider2D playerCollider;
public Collider2D obstacleCollider;
public void Start() => Physics2D.IgnoreCollision(playerCollider, obstacleCollider);
I have a very simple script I use to handle collisions in my games.
It's very easy to setup because it makes everything drop and draggable, which is a much easier way to program.
Below is the script and below that is instructions on how to use. Note it is a layer based system, but you can select multiple layers.
[System.Serializable]
public class TriggerEvent : UnityEvent<Collider> { }
[System.Serializable]
public class CollisionEvent : UnityEvent<Collision>{ }
public class EnterEvent: MonoBehaviour
{
public TriggerEvent TriggerEnteredEvent;
public CollisionEvent CollisionEnteredEvent;
[SerializedField]private LayerMask validLayers;
// Initalize Event System
void Awake()
{
if (OnTriggerEnter == null)
{
TriggerEnteredEvent = new TriggerEvent();
}
if (OnCollisionEnter == null)
{
CollisionEnteredEvent = new CollisionEvent();
}
}
// Called if transform is a trigger
void OnTriggerEnter(Collider collider)
{
if (validLayers == (validLayers | 1 << collider.gameObject.layer))
{
TriggerEnteredEvent?.Invoke(collider);
}
}
// Called if transform is not a trigger
void OnCollisionEnter(Collision collision)
{
if (validLayers == (validLayers | 1 << collision.gameObject.layer))
{
CollisionEnteredEvent?.Invoke(collision);
}
}
}
This is how it would work, and in this example I will be "coding" it from the perspective of a Bullet.
Basically I want to check if I (The Bullet) hits either the terrain or an enemy then call the relevent funcitons in the Bullet class respectively.
Obviously if I hit an enemy I want to deal damage.
So this will be my example bullet class
public class Bullet : MonoBehaviour
{
public int BulletDamage = 10;
public int BulletSpeed = 5;
void FixedUpdate() => transform.position = Vector3.Lerp(transform.position, transform.position + transform.forward * speed * Time.deltaTime, 1f);
public void OnEnemyHit(Collision collision)
{
// Try to get the enemy script
Enemy enemy = collision.gameObject.transform.GetComponent<Enemy>();
if (enemy != null)
{
enemy.DealDamage(this.BulletDamage);
}
}
public void OnTerrainHit(Collision collision)
{
Destroy(this.gameObject);
}
}
Add the EnterEvent script to the bullet.
Add the Bullet Script to the bullet.
There will be a space on the Inspecter where you can add your events. It should have a Plus and Minus in the top right corner. Press the plus.
From the inspector drag the bullet in game GameObject to the open space provider.
In the dropdown to the right, click on it, look for the Bullet Script, and select the OnEnemyHit function from it.
Create another event, do the exact same, but this time select the OnTerrainHit funciton instead - now but would be called in the order you added them.
Just underneath the event system should be the be able to see a dropdown for the Layers. Select all the layers you want your bullet to interact with. In this case it will be the Enemy and Terrain.
Finally remember to setup your layers properly. Ensure the Enemy has an Enemy Layer, the Terrain has a Terrain Layer, Bullet bullet layer and Player has a Player Layer
So I created a plane to be my floor in my unity project. I also assigned that with a mesh collider and a box collider and set it with convex but not as trigger.
I then created an item with also a mesh and sphere collider and set it to use gravity, since I wanted the item to fall onto the floor. But when I start the game, it still falling past the floor.
I have tried to find a solution already in YT, here and other places, but the only ideas they give is assigning a collider. This doesn't work as for me.
I also tried to fill the colliders with materials but cannot assign anything with it.
I also tried to write a code, but this does not help either.
Does anyone have an idea how to solve it?
public class IsGrounded : MonoBehaviour
{
Vector3 velocity;
public float gravity = -9.81f;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
bool isGrounded;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
}
}
So finally, I manage to find the solution from a helpful yt video.
What I needed to change was to deactivate both, the floor and the items, the trigger event. Since Unity does not allow you to use without kinematic and convex, I just clicked on convex and nothing changes. Now, items will not fall down the plane (still can happen, like when I throw the item down, it will sometimes go through).
my code is pretty simple, but im quite new to unity... im trying to make it so i can drop my items on the ground when i drag the out of my inventory, but cant quite manage to do so, with a few consistent errors. I have a prefab (just learned of those today), which im trying to change its sprite renderer and spawn it. Heres my code:
public class ItemWorld : MonoBehaviour
{
private Transform prefab;
private Item item;
private SpriteRenderer spriteRenderer;
void Start()
{
prefab = Resources.Load("Prefabs/pfItemWorld") as GameObject;
//myPrefab = Resources.Load("Prefabs/pfItemWorld");
}
public static ItemWorld spawnItemWorld(Vector3 position, Item item)
{
Transform transform = Instantiate(prefab, position, Quaternion.identity);
ItemWorld itemWorld = transform.GetComponent<ItemWorld>();
itemWorld.SetItem(item);
return itemWorld;
}
private void Awake()
{
spriteRenderer = GetComponent<SpriteRenderer>();
}
public void SetItem(Item item)
{
this.item = item;
Rect spriteRect = new Rect(0, 0, item.itemIcon.width, item.itemIcon.height);
Sprite mySprite = Sprite.Create(item.itemIcon, spriteRect, new Vector2(0.5f, 0.5f));
spriteRenderer.sprite = mySprite;
}
}
My problem is i cant manage to load my prefab and use it in Instantiate without many errors...
What is wrong with my code?
Here are the errors:
(1) Assets\Scripts\ItemWorld.cs(12,18): error CS0029: Cannot implicitly convert type 'UnityEngine.GameObject' to 'UnityEngine.Transform' (yes, i know what this means, but how can i use a prefab without transform)
(2)Assets\Scripts\ItemWorld.cs(17,43): error CS0120: An object reference is required for the non-static field, method, or property 'ItemWorld.prefab'
I have tried to research but this is my last hope xd
Ill be happy for ANY help,
thanks ahead,
Gambizon
Prefabs are GameObjects and need to be instantiated and declared as such. private transform prefab should be private GameObject prefab.
After you've instantiated the object with
GameObject prefabObject = Instantiate(prefab, position, Quaternion.identity);
You can then use Transform transform = prefabObject.transform; to get the transform component of your newly instantiated prefab.
Also, if you make the prefab reference in the script public, and have this script attached to a GameObject, you can drag the prefab into the inspector so that you don't need Resources.Load("Prefabs/pfItemWorld") as GameObject, as the reference will already be there before run time.
so I'm developing a game for android in LibGDX and I've stumbled upon a problem: I have a scene with an image in it and I want to be able to click/touch the image and make stuff happen after doing so.
I've been trying to google a solution for the past day but I keep on missing something vital. Here's my code:
public class ScreenSplash implements Screen {
private Texture textureGlobe = new Texture(Gdx.files.internal("graphics/splash.png"));
private Image imageGlobe = new Image((new TextureRegion(textureGlobe)));
public ScreenSplash() {
imageGlobe.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log(Game.LOG, "image clicked");
return true;
}
});
stageGame.addActor(imageGlobe);
}
...
}
I've also heard that I'm supposed to put this somewhere:
Gdx.input.setInputProcessor(inputProcessor);
But I don't really know what to do with it.
Your Stage is your InputProcessor so do something like Gdx.input.setInputProcessor(stageGame);. The Stage will route the events to the actors.
Ah, I've found out what the problem was.
I imported java.awt.event.InputEvent instead of com.badlogic.gdx.scenes.scene2d.InputEvent and the touchDown function wasn't properly overriden because of this.