Touch and Drag Sprite in Andengine - andengine

I'm trying to make a sprite so when you touch it and drag your finger, the sprite follows your movement. I've tried to follow the AndEngine examples, but they are part of GLES1. I'm using GLES2.
Within my code, the onAreaTouched is being called, but it is not continuously being called to update the sprite with my finger.
Thanks in advance.
public class RectangleFactory extends Sprite {
public float randomNumber;
public RectangleFactory(float pX, float pY, ITextureRegion pTextureRegion,
VertexBufferObjectManager pVertexBufferObjectManager) {
super(pX, pY, pTextureRegion, pVertexBufferObjectManager);
// TODO Auto-generated constructor stub
Random random = new Random();
randomNumber = (float) random.nextInt(BallShakeActivity.CAMERA_WIDTH);
};
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float X, float Y)
{
Log.d("Mark", "circles are touched");
this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2, pSceneTouchEvent.getY() - this.getHeight() / 2);
if(pSceneTouchEvent.isActionMove()){
Log.d("Mark", "finger is moving");
}
return true;
};
#Override
protected void onManagedUpdate(final float pSecondsElapsed){
if(this.mY > 0f){
}
else{
Random random = new Random();
randomNumber = (float) random.nextInt(BallShakeActivity.CAMERA_WIDTH);
this.setPosition(randomNumber, 800f);
}
super.onManagedUpdate(pSecondsElapsed);
}
}

You can find some examples, including a touch-drag example, for AndEngine GLES2 in the AndEngineExamples repository on Nicolas' Github page.
https://github.com/nicolasgramlich/AndEngineExamples
The examples seem to be mostly for the GLES2 branch but there may also be some examples for the GLES2-AnchorCenter branch as well.
Some of the code works with GLES1/master branch but you're mostly on your own for examples for that branch.

Related

Why are my programmatically instantiated Prefabs not firing mouse events?

In my Unity project I'm instantiating 20 Prefabs. These prefabs have box colliders and an attached script that includes:
private void OnMouseEnter()
{
print($"Mouse Enter detected by: {this.name}");
}
However these events never fire. If you google this issue you'll find multiple posts about this going back more than a decade. Unfortunately none of those threads seem to include a solution. If I drag the Prefab into the scene the mouse events will work, but if I create them programmatically they do not. Can someone explain to me how I can get mouse events working on programmatically created prefabs?
EDIT:
Since someone asked for my instantiation code here it is:
foreach (var movie in movies.Select((value, index) => (value, index)))
{
float angle = movie.index * Mathf.PI * 2 / movies.Count;
float x = Mathf.Cos(angle) * radius;
float z = Mathf.Sin(angle) * radius;
Vector3 pos = transform.position + new Vector3(x, height, z);
float angleDegrees = -angle * Mathf.Rad2Deg;
Quaternion rot = Quaternion.Euler(0, angleDegrees, 0);
var pre = Instantiate(moviePrefab, pos, rot, carousel.transform);
pre.transform.LookAt(Vector3.zero);
}
You didn't give me many details but I made what you want to do and this is how.
I made two classes:
NewBehaviourScript - for instatiating prefabs
public class NewBehaviourScript : MonoBehaviour
{
public GameObject Prefab;
private void Start()
{
for (int i = 0; i < 10; i++)
{
Instantiate(Prefab, new Vector3(transform.position.x + i, transform.position.y, 0), Quaternion.identity);
}
}
}
PrefabScript - script for prefab
public class PrefabScript : MonoBehaviour
{
private void OnMouseDown()
{
Debug.Log("Hit");
}
}
I created empty object "InstatiateObjectsHelper" in scene with the NewBehaviourScript
Then I created a prefab by creating it in the hierarchy, added to it PrefabScript, added to it BoxCollider, and then dragged & dropped it into the assets window.
Pressed play and tested it and it is working how you want it to.

Unity: Rotation sync over network on dedicated server

This was probably asked a dozen of times, but I can't seem to find the answer anywhere.
I have a dedicated server for a space game written in C# console application. The problems that I'm facing is the synchronisation of GameObject rotations. I'm suspecting the issue being related to gimbal lock, but I am not sure.
Here I have my player movement/rotation controller:
public class PlayerMovement : MonoBehaviour {
[SerializeField] float maxSpeed = 40f;
[SerializeField] float shipRotationSpeed = 60f;
Transform characterTransform;
void Awake()
{
characterTransform = transform;
}
void Update()
{
Turn();
Thrust();
}
float Speed() {
return maxSpeed;
}
void Turn() {
float rotX = shipRotationSpeed * Time.deltaTime * CrossPlatformInputManager.GetAxis("Vertical");
float rotY = shipRotationSpeed * Time.deltaTime * CrossPlatformInputManager.GetAxis("Horizontal");
characterTransform.Rotate(-rotX, rotY, 0);
}
void Thrust() {
if (CrossPlatformInputManager.GetAxis("Move") > 0) {
characterTransform.position += shipTransform.forward * Speed() * Time.deltaTime * CrossPlatformInputManager.GetAxis("Move");
}
}
}
This script is applied to my character object which is a ship. Note that the character object has a child object which is the ship itself and has fixed rotation and position that do not change. When character has moved/rotated I send the following to the server: position(x, y, z) and rotation(x, y, z, w).
Now here is the actual script that receives network packet information and updates the other players in game:
public class CharacterObject : MonoBehaviour {
[SerializeField] GameObject shipModel;
public int guid;
public int characterId;
public string name;
public int shipId;
Vector3 realPosition;
Quaternion realRotation;
public void Awake() {
}
public int Guid { get { return guid; } }
public int CharacterId { get { return characterId; } }
void Start () {
realPosition = transform.position;
realRotation = transform.rotation;
}
void Update () {
// Do nothing
}
internal void LoadCharacter(SNCharacterUpdatePacket cuPacket) {
guid = cuPacket.CharacterGuid;
characterId = cuPacket.CharacterId;
name = cuPacket.CharacterName;
shipId = cuPacket.ShipId;
realPosition = new Vector3(cuPacket.ShipPosX, cuPacket.ShipPosY, cuPacket.ShipPosZ);
realRotation = new Quaternion(cuPacket.ShipRotX, cuPacket.ShipRotY, cuPacket.ShipRotZ, cuPacket.ShipRotW);
UpdateTransform();
Instantiate(Resources.Load("Ships/Ship1/Ship1"), shipModel.transform);
}
internal void UpdateCharacter(SNCharacterUpdatePacket cuPacket) {
realPosition = new Vector3(cuPacket.ShipPosX, cuPacket.ShipPosY, cuPacket.ShipPosZ);
realRotation = new Quaternion(cuPacket.ShipRotX, cuPacket.ShipRotY, cuPacket.ShipRotZ, cuPacket.ShipRotW);
UpdateTransform();
}
void UpdateTransform() {
transform.position = Vector3.Lerp(transform.position, realPosition, 0.1f);
transform.rotation = Quaternion.Lerp(transform.rotation, realRotation, 0.5f);
}
}
Do you see anything wrong with the code ?
My experience with 2 players in game is the following:
When I start the game with two players they spawn at the same location (0,0,0) and same rotation (0,0,0).
Lets say that The other player is rotating continuously around the X-axis only. What I am experiencing is:
First 90 deg. of rotation it renders fine.
Next 180 deg. of rotation the object stays in place
The last 90 deg. of rotation renders fine
In the first version I did not send the 'w' value of Quaternion, but then added it in the second version and it did not help. Note that there is no restrictions in rotation and users can rotate endlessly in all directions.
Btw the positioning works fine.
I might not understand Quaternions fully, but I thought that they had a purpose in avoiding the gimbal lock issue.
Any help would be appreciated.
To answer my own question. I used transform.localEulerAngles instead of transform.rotation, and everything seems to work just fine.
Now the only thing that I am unsure is if gimbal lock could happen with this change.

Unity Change UI Z-Axis

I'm creating an Archery, Platformer, Shooting game named "ArcheryRun" with a small team. We have a powerbar (shown in orange) which increases as you hold down the "Left Mouse Button". However since its a UI element it is static in a position.
I would like it to appear above the player when they change their z-axis as Ive done with the Arrow Image by using a 2D Sprite object. However I can't seem how to change the z-axis of a UI Image relative to the player or use a Game Object which allows a fill option.
Any help is appreciated, thanks :)
Change Orange Powerbar to Follow Player
If we understand your question, this should work:
This method gives you screen canvas position from world position:
public static Vector3 GetScreenPositionFromWorldPosition(Vector3 targetPosition)
{
Vector3 screenPos;
screenPos = Camera.main.WorldToScreenPoint(targetPosition);
return new Vector3 (screenPos.x, screenPos.y, 0f);
}
Then you need a script on top of power bar, lets say like this:
public class PowerBar : MonoBehaviour
{
public Transform target;
RectTransform _rectTransform;
void Awake ()
{
_rectTransform = GetComponent<RectTransform> ();
}
public void updatePosition()
{
Vector3 pos = YourStaticClassWith.GetScreenPositionFromWorldPosition (target.position);
Vector2 rpos = pos;
_rectTransform.anchoredPosition3D = rpos + Vector2.up * 100f; // 100f is value of how many pixels above the target that UI element should apear
}
void LateUpdate()
{
updatePosition ();
}
}
The target is basicly transform of your player object.
The 100f value represents pixels above the target.

Rotate camera based on mouse postitions around a object Unity3D

Okay, So I have come this far:
public class CameraScript : MonoBehaviour {
public void RotateCamera()
{
float x = 5 * Input.GetAxis("Mouse X");
float y = 5 * -Input.GetAxis("Mouse Y");
Camera.mainCamera.transform.parent.transform.Rotate (y,x,0);
}
}
My camera has a parent which I rotate based on my mouse position. The only problem is that I can only swipe with the mouse to rotate the object. How can I rotate the object which is my camera is attached to based on my mouse position if I just click next to the object. Thanks in advance!
The value will be in the range -1...1 for keyboard and joystick input.
If the axis is setup to be delta mouse movement, the mouse delta is
multiplied by the axis sensitivity and the range is not -1...1. Unity Document
Note: This link is usefull please check it.
So you need to change your code like this.
public void RotateCamera()
{
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); // Gets mouse position to Unity World coordinate system
Camera.mainCamera.transform.parent.transform.Rotate (mousePosition);
}
if there are problem you can do like this
public void RotateCamera()
{
Vector3 position = new Vector3(Input.mousePosition.x, Input.mousePosition.y,0);
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(position); // Gets mouse position to Unity World coordinate system
Camera.mainCamera.transform.parent.transform.Rotate (mousePosition);
}
one more option is rotateTowards.
public float speed=10; //any value > 0
public void RotateCamera()
{
Vector3 targetDir = Camera.main.ScreenToWorldPoint(Input.mousePosition) - Camera.mainCamera.transform.parent.transform.position;
float step = speed * Time.deltaTime;
Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0F);
Camera.mainCamera.transform.parent.transform.rotation = Quaternion.LookRotation(newDir);
}
Maybe some syntax errors, i don't check them.

How to get touched location in AndEngine?

I'm new in AndEngine and there is too many hard things for me now..
I want to know where I touched when I touch anywhere, and give actions by those locations with x and y. Can anybody help me?
Go throught the AndEngine Examples. There are two methods. Either you register touch on an Entity, as shown for example in TouchAndDrag example:
final Sprite sprite = new Sprite(centerX, centerY, this.mFaceTextureRegion, this.getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2, pSceneTouchEvent.getY() - this.getHeight() / 2);
return true;
}
};
Or you use the touch listener on a Scene. You have to implement the IOnSceneTouchListener and then set it in your scene:
public class MyListener implements IOnSceneTouchListener {
#Override
public boolean onSceneTouchEvent(Scene pScene, final TouchEvent pSceneTouchEvent) {
if (pSceneTouchEvent.isActionDown()) {
//execute action.
}
return false;
}
}
}
...
scene.setOnSceneTouchListener(new MyListener ());
You can find most of the code needed in the examples already. See this tutorial on how to add them to Eclipse.