- Home /
Moving 2D player only one Hex, Flat Top, on mouse click, only to hexes next to player
I am very new to all of this and am trying to piece together many tutorials, but figured after 6-7 hours of them not being specific to my issue I was better off asking for help.
I am sure however I am doing this is wrong and convoluted, so I am open to hearing corrections. My aim here is learning. First here is what I have for a grid. Hexagons with flat tops (almost every movement tutorial was pointed top, this made it difficult)
The white Hex is the player (game object Player). The ball is the game object I want to move before the player to check for collision data (game object PlayerMovePoint). There are 6 game objects that surround the player and are attached to it as children (those are the hexes with transparency around them next to the player) (top, topleft, bottomleft, bottom, bottomright, topright)
I made a script called playerMovementGrid and created gameobjects within the script for each hex surrounding the player(top, topleft,bottomleft, etc). I then attached those game objects to the script.
I tried all kinds of Vector3 movements to try to detect what object (topleft, top, topright, etc) was clicked, and then move the PlayerMovePoint ball to that grid. If it did not detect collision, then the player (and in turn all its children, the grid surrounding it) also moved.
I tried getting the mouse location, I tried detecting which object was clicked with
if (eventData.pointerCurrentRaycast.gameObject.name == "upperright")
which clearly was not correct, as it wouldn't give me a debug message when I attached one.
I will attach the mess of code that is my latest attempt that I used, but I am sure it is all 100% useless and wrong and that I should be starting again with something more simple. (There is no collision detection in this script, I was going to try to figure that out after, though I have a collision layer and collision items)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerMovementGrid : MonoBehaviour, IPointerDownHandler
{
public Transform movePoint;
public float moveSpeed = 5f;
public GameObject topRight;
public GameObject bottomRight;
public GameObject bottomLeft;
public GameObject topleft;
public GameObject top;
public GameObject bottom;
public GameObject CurrentObject;
private void Start()
{
movePoint.parent = null;
AddPhysics2DRaycaster();
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
Debug.Log(Input.mousePosition);
if (eventData.pointerCurrentRaycast.gameObject.name == "upperright")
{
movePoint.position += Vector3.MoveTowards(transform.position, topRight.transform.position , Time.deltaTime * moveSpeed) ;
}
}
private void AddPhysics2DRaycaster()
{
Physics2DRaycaster physicsRaycaster = FindObjectOfType<Physics2DRaycaster>();
if (physicsRaycaster == null)
{
Camera.main.gameObject.AddComponent<Physics2DRaycaster>();
}
}
}
Apologizes that this is all incorrect and Surely I need to start over. I have only been learning code and unity for a few days.
I guess in the end I want to know why my attempts are failing, and what I should have been doing this entire time (and I really don't know how to determine how far I need to move my player to line up in one of the grid cells, X, Y, Z)
Any help or even links to FLAT top based hex tutorials that LIMIT movement to one grid next to you (most I've found move you as far as you want, I only want to move ONE grid, as the player will have Action Points per turn, and if that is at 0, they cannot move)
My goal is to move the playerMovePoint ONE grid, check for Collision, and if there is none (and player has an action point), then the Player moves to the grid that was clicked. (and now the playerMovePoint and the Player should both be in the same spot)
Thank you if you read this far. Please keep in mind my low knowledge level when explaining.
Answer by Caeser_21 · May 19 at 07:18 AM
What if you try using mouse position and Raycasts instead to handle the movement and detection? I have personally never used IPointerDownHandler
, so I don't know much about it... Just a suggestion though
This is the fully revised and working (I think) code :
private Camera Cam; //Add this at the top
private void Start()
{
Cam = Camera.main;
}
private void Update()
{
if (Input.GetMouseButtonDown(0)) //Left click
{
CheckBlock();
}
}
private void CheckBlock()
{
Vector3 MousePos = Cam.ScreenToWorldPoint(Input.mousePosition);
Vector3 RayMousePos = new Vector3(MousePos.x, MousePos.y, 1f);
RaycastHit Hit;
if (Physics.Raycast(RayMousePos, Vector3.back, out Hit))
{
//Here is where you check whether there is any collision
transform.position = Hit.tranform.position;
}
}
NOTE : Make sure the Camera in-game has the default tag (i think it is "MainCamera")
Thanks for the idea.
I found some tutorials with Raycasts that I attempted before this solution, but I could not manage to figure out how to get it to move to the correct location (to the next hex location surrounding), and any of the examples I managed to make work to move a "player" object at all only worked left / right, up / down for pointed hex grids, and not mouse clicks, so they didn't work for my grid types (and were keyboard, rather than mouse. it mostly just broke things because as I said I am very new to this)
I am not sure how to get the correct mouse click (like on any of the surrounding hexes I have made), and then tell the player to try to move to that location. I am open to a raycast solution instead, I just haven't been able to find tutorials for doing so with Flat top Hex and only being able to move on hex (rather than point and click and move to any hex visible)
I almost gave up and was going to start again and re-do assets using hex with points, but thought I would not learn anything if I did that.
There aren't many tutorials explaining raycasts in that way... The way leant is mainly through trial and error
Incase all the hexagons are gameobjects then you can just shoot a raycast and move to the raycast's hit position... I can provide a code example if needed :)
All of the hexagons surrounding the player are game objects (named top, topleft, topright, bottom, bottemleft, bottomright).
If I can use raycasts in the way you are describing, I would be more than happy to use that solution. What I wasn't sure of is how to ensure it goes to the correct grid location. As in, I want to make sure it doesn't move to exactly where the mouse click coordinates are, because if they are slightly off over and over then eventually the grids won't line up at all.
I need to make sure it detects I am clicking that specific object (lets say, bottomleft for example) and then move the player to bottomleft after it checks there is no collision)
If you could provide a code example I would really appreciate it. I agree trial and error is the best way to do things, but after wasting an entire day and staying up till 4am trying to figure it out, I'd love to see some code that I could learn from.
If I could use raycasting to see what hex i clicked (so again, lets say bottomleft) and then move the object I have called playerMovePoint to that spot to check for collision, and if none, move both Player and PlayermovePoint there with Raycast as you describe, that would be amazing.