OnMouseDown in prefab not working with some scene - unity3d

I have prefab enemyRangeAttack and then I add this code for enemy (child of enemyRangeAttack)
public class Selectable : MonoBehaviour{
[HideInInspector] public GameObject Player;
public float range = 10f;
private void Awake()
{
Player = GameObject.FindGameObjectWithTag("Player");
}
private void OnMouseDown()
{
Debug.LogWarning("Mouse down "+ gameObject);
float dist = Vector3.Distance(Player.transform.position, transform.position);
if (dist < range)
{
Selected();
}
}
public void Selected()
{
GameObject newSelection = ObjectPooler.instance.SpawnFromPool(
"Mark",
transform.GetChild(0).gameObject.transform.position,
Quaternion.identity
);
newSelection.transform.SetParent(transform);
}
}
Game object enemyRangeAttack have circle collider2d and trigger is on and Game object enemy have too
And I have 3 scene, method OnMouseDown() not working for all my scene. How can I fix this

Related

Unity Physics2D.OverlapBox is always returning true

I am trying to do ground detection for a 2d platformer, but my physics check is always returning true. I am reusing code that I have used a many times before:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
[Header("MOVEMENT")]
public float speed;
float inputX;
[Header("JUMPING")]
public float jumpForce;
public Transform feet;
public Vector2 checkSize;
public bool isGrounded;
public LayerMask layers;
public int extraJumps = 1;
int jumpTracker;
private Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
inputX = Input.GetAxisRaw("Horizontal");
isGrounded = Physics2D.OverlapBox(feet.position, checkSize, 0f, layers);
if(Input.GetKeyDown(KeyCode.Space))
{
if (isGrounded)
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
jumpTracker = extraJumps;
}
else
{
if(jumpTracker > 0)
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
jumpTracker--;
}
}
}
}
private void FixedUpdate()
{
rb.velocity = new Vector2(inputX * speed, rb.velocity.y);
}
private void OnDrawGizmos()
{
Gizmos.DrawWireCube(feet.position, checkSize);
}
}
In the scene there is a Tilemap with a composite collider tagged as ground that the player is colliding with.
I have tried everything I can think of and still have no idea what is causing this issue. Any help would be greatly appreciated.

When the player is grounded plays the falling and landing animation in an eternal loop

Capsule Collider height: 2; Capsule Collider radius: 0.5 While the
player is rgounded the Grounded the Falling and Grounded parameters
turn on and off continuously. This is the project (unity package)
Conditions: From Movements to Jump, Jump parameter has to be
triggered. From Jump to Falling, Falling parameter has to be true.
From Falling to Landing, Grounded parameter has to be true. From
Movements to Falling, Falling parameter has to be true.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Game.Manager;
public class PlayerController : MonoBehaviour
{
InputManager inputManager;
Animator animator;
Rigidbody playerRb;
CapsuleCollider collider;
bool hasAnimator;
bool grounded;
[SerializeField] float jumpFactor = 250f;
float Dis2Ground;
[SerializeField] LayerMask GroundCheck;
[SerializeField] float airResistance = 0.8f;
void Start()
{
collider = GetComponent<CapsuleCollider>();
Dis2Ground = collider.bounds.extents.y;
inputManager = GetComponent<InputManager>();
playerRb = GetComponent<Rigidbody>();
hasAnimator = TryGetComponent<Animator>(out animator);
fallingHash = Animator.StringToHash("Falling");
jumpHash = Animator.StringToHash("Jump");
groundHash = Animator.StringToHash("Grounded");
}
private void FixedUpdate()
{
HandleJump();
SampleGround();
}
private void HandleJump()
{
if (!hasAnimator) return;
if (!inputManager.Jump) return;
animator.SetTrigger(jumpHash);
}
public void JumpAddForce()
{
playerRb.AddForce(Vector3.up * jumpFactor, ForceMode.Impulse);
playerRb.AddForce(-playerRb.velocity.y * Vector3.up, ForceMode.VelocityChange);
animator.ResetTrigger(jumpHash);
}
private void SampleGround()
{
if (!hasAnimator) return;
RaycastHit hitInfo;
if(Physics.Raycast(transform.position, Vector3.down, out hitInfo, Dis2Ground + 0.1f))
{
grounded = true;
SetAnimationGrounding();
return;
}
Debug.Log(grounded);
animator.SetFloat(zVelHash, playerRb.velocity.y);
grounded = false;
SetAnimationGrounding();
return;
}
private void SetAnimationGrounding()
{
animator.SetBool(fallingHash, !grounded);
animator.SetBool(groundHash, grounded);
}
}

Unity: 3D top-down rotate item around player

I'm trying to get an object to always be "in front" of the player, from a top down perspective. Here's screenshots demonstrating what I'm trying to do.
So as you can see, when the blue capsule (player) picks up the green capsule (item), the item correctly hovers in front of the player (indicated by the z-axis blue arrow), but when the player turns in any other direction, the item doesn't follow, and instead stays in exactly the same position relative to the player.
My player controller script looks as follows:
using UnityEngine;
public class PlayerController : MonoBehaviour {
public float movementSpeed = 10;
private Rigidbody body;
private Vector2 movement;
void Start() {
body = GetComponent<Rigidbody>();
}
void Update() {
movement.x = Input.GetAxis("Horizontal");
movement.y = Input.GetAxis("Vertical");
}
void FixedUpdate() {
body.velocity = new Vector3(movement.x * movementSpeed * Time.deltaTime, 0, movement.y * movementSpeed * Time.deltaTime);
// this is what updates the direction of the blue arrow in the direction of player movement
if(movement.x != 0 || movement.y != 0) {
body.rotation = Quaternion.LookRotation(body.velocity);
}
}
}
And here's my pickup script (where the item's position is supposed to be updated):
using UnityEngine;
public class Pickup : MonoBehaviour {
private GameObject item;
public float carryDistance = 1;
void OnCollisionEnter(Collision collision) {
if(collision.gameObject.CompareTag("Item")) {
item = collision.gameObject;
}
}
void Update() {
if(item) {
item.transform.position = transform.position + new Vector3(0, 0, carryDistance);
}
}
}
So to reiterate my question: How can I update the item's position such that it's always hovering next to the player on the side of the blue arrow?
You can achieve this by using players transform.forward
item.transform.position = transform.position + (transform.forward * carryDistance)
+ (Vector3.up * carryHeight);
Alternatively you can just add empty child gameobject to the player, position it in front of the player and use its transform position and rotation to position the picked up object.
public class Pickup : MonoBehaviour {
public Transform pickupPositionTransform;
private GameObject item;
public float carryDistance = 1;
void OnCollisionEnter(Collision collision) {
if(collision.gameObject.CompareTag("Item")) {
item = collision.gameObject;
}
}
void Update() {
if(item) {
item.transform.position = pickupPositionTransform.position;
item.transform.rotation = pickupPositionTransform.rotation;
}
}
}

Efficient way to detect touch except on the area of joystick

I'm using this joystick and Mirror for networking
https://github.com/herbou/Unity_EasyJoystick
And I have this script to fire a bullet on the user touch
public class ShootBullet : NetworkBehaviour
{
[SerializeField]
private GameObject bulletPrefab;
private GameObject bullet;
// Set via the Inspector in Units/second
[SerializeField] private float _moveSpeed = 2f;
[SerializeField] private Camera _camera;
Vector3 touch_Pos = new Vector3(0, 0, 0);
private void Awake()
{
if (!_camera) _camera = Camera.main;
}
void Update()
{
if (Input.touchCount > 0 && this.isLocalPlayer)
{
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
var touch = Input.GetTouch(0);
touch_Pos = _camera.ScreenToWorldPoint(touch.position);
this.CmdShoot();
}
}
if (bullet != null)
{
bullet.transform.position = Vector3.MoveTowards(bullet.transform.position, touch_Pos, _moveSpeed * Time.deltaTime);
}
}
[Command]
void CmdShoot()
{
bullet = Instantiate(bulletPrefab, this.transform.position, Quaternion.identity);
NetworkServer.Spawn(bullet);
}
}
My problem right now is it's firing a bullet when I touch the joystick area. What is the efficient way to exclude input.touch on the joystick area
You can raycast touch position and check the result.
var mousePos = Input.mousePosition;
var mouseToRay = _camera.ScreenPointToRay(mousePos);
RaycastHit hit;
if (Physics.Raycast(mouseToRay, out hit))
{
var gameObject = hit.collider.gameObject;
//Here You can check the name of your object or the layer or tag
var isMouseUnderJoyStick = gameObject.CompareTag("Your_UI_Tag");
}
And you have to add collider component to your JoyStick

Trying to create a nice character controller?

I'm kind of new in the 2D environment of Unity.
I'm trying to create a platformer. For now, I have a simple map and my player.
My simple map and my player
My player have one script attached :
public class Player : MonoBehaviour
{
public float speed;
public float jump;
public GameObject raycastPoint; // Positioned at 0.01 pixel below the player
private SpriteRenderer spriteRenderer;
private Rigidbody2D body; // Gravity Scale of the Rigidbody2D = 50
private Animator animator;
private void Start()
{
spriteRenderer = GetComponent<SpriteRenderer>();
body = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
}
private void Update()
{
float horizontal = Input.GetAxisRaw("Horizontal");
if (horizontal == 1 && spriteRenderer.flipX)
{
spriteRenderer.flipX = false;
}
else if (horizontal == -1 && !spriteRenderer.flipX)
{
spriteRenderer.flipX = true;
}
body.velocity = new Vector2(horizontal * speed, body.velocity.y);
animator.SetFloat("Speed", Mathf.Abs(horizontal));
float vertical = Input.GetAxisRaw("Vertical");
if (vertical == 1)
{
RaycastHit2D hit = Physics2D.Raycast(raycastPoint.transform.position, Vector2.down, 0.01f);
if (hit.collider != null)
{
body.AddForce(new Vector2(0f, jump));
}
}
}
}
For now I have achieved the right and left movements.
For the jump, I have a child gameobject just under the player and I'm firing a raycast to the bottom so I can know if my player is grounded or not.
I have two problems.
PROBLEM NUMBER ONE.
Sometimes I feel like my "AddForce" line is executed multiple times my player is jumping really high
Problem number one image
PROBLEM NUMBER TWO.
When I'm jumping to the left or right wall, if I keep pressing the left or right key my player is not falling anymore and stay against the wall.
Problem number two image
I tried to put my code into the FixedUpdate method (I know it's better) but I had the same results.
And I tried to set the Collision Detection on Continuous but I had the same results.
Try this code for your first problem :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(BoxCollider2D))]
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(Animator))]
public class Player_Controller : MonoBehaviour {
private Rigidbody2D body;
private bool canJump, facingRight;
private Animator anim;
[SerializeField]
private float moveSpeed, jumpForce;
void Start ()
{
SetStartValues();
}
void FixedUpdate ()
{
float horizontal = Input.GetAxis("Horizontal");
animator.SetFloat("Speed", Mathf.Abs(horizontal));
Flip(horizontal);
Move(horizontal);
Jump();
}
private void SetStartValues()
{
body = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
canJump = true;
facingRight = true;
}
private void Jump()
{
if (Input.GetKeyDown(KeyCode.Space) && canJump)
{
body.AddForce(new Vector2(0, jumpForce));
canJump = false;
}
}
private void Move(float x)
{
body.velocity = new Vector2(x * moveSpeed * Time.deltaTime, body.velocity.y);
}
private void Flip(float x)
{
if (x > 0 && !facingRight|| x < 0 && facingRight)
{
facingRight = !facingRight;
transform.localScale = new Vector2(transform.localScale.x * -1, transform.localScale.y) ;
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Ground")
{
canJump = true;
}
}
}
And don't forget to put the "Ground" tag on your ground object.