G'day all,
In short, I'm using a for loop to create a bunch of identical sprites that I want to bounce around the screen. The problem is how do I write a collision detection process for the sprites. I have used the process of placing rectangles around sprites and using the .intersects method for rectangles but in that case I created each sprite separately and could identify each one uniquely. Now I have a bunch of sprites but no apparent way to pick one from another.
In detail, if I create an object called Bouncer.cs and give it the movement instructions in it's update() method then create a bunch of sprites using this in Game.cs:
for (int i = 1; i < 5; ++i)
{
Vector2 position = new Vector2(i * 50, i * 50);
Vector2 direction = new Vector2(i * 10, i * 10);
Vector2 velocity = new Vector2(10);
Components.Add(new Bouncer(this, position, direction, velocity, i));
}
base.Initialize();
I can draw a rectangle around each one using:
foreach (Bouncer component1 in Components)
{
Bouncer thing = (Bouncer)component1;
Rectangle thingRectangle;
thingRectangle = new Rectangle((int)thing.position.X, (int)thing.position.Y, thing.sprite.Width, thing.sprite.Height);
But now, how do I check for a collision? I can hardly use:
if (thingRectangle.Intersects(thingRectangle))
I should point out I'm a teacher by trade and play with coding to keep my brain from turning to mush. Recently I have been working with Python and with Python I could just put all the sprites into a list:
sprites[];
Then I could simply refer to each as sprite[1] or sprite[2] or whatever its index in the list is. Does XNA have something like this?
Please let me know if any more code needs to be posted.
Thanks,
Andrew.
One solution, which I use in my game engine, is to have a Logic code run inside the objects for every game Update, ie. every frame. It seems you already do this, according to the variable names, which indicate you run some physics code in the objects to update their positions.
You might also want to create the collision rectangle inside the Bouncer's constructor so it's more accessible and you make good use of object oriented programming, maybe even make it an accessor, so you can make it update every time you call it instead of manually updating the bounding/collision box. For example:
public Rectangle #BoundingBox {
get { return new Rectangle(_Position.X, _Position.Y, width, height); }
}
Whichever way works, but the collision checks can be run inside the Bouncer object. You can either make the reference list of the Bouncer objects static or pass it to the objects itself. The code for collisions is very simply:
foreach(Bouncer bouncer in Components) //Components can be a static List or you can pass it on in the constructor of the Bouncer object
{
if (bouncer.BoundingBox.Intersects(this.BoundingBox))
{
//they collided
}
}
Related
I'm currently working on RPG graphically very similar to Runescape (old school), but with my own game system. I am not sure what is the best way to have interchangeable armor system. I am going to create low poly models, as i said, similar to runescape models like here, and want to have possibility to have random variations of armor like here.
There are two ways as I understand, first is just to change mesh of my character model, the second one is to create model of my character and use the bones weights to armor models. I know there is whole topic about the first option here (couldn't make 3rd link) forum.unity3d.com/threads/stitch-multiple-body-parts-into-one-character.16485/, but really? Every qeustion about something similar leads to this topic. But its like 8 years old and for Unity 2.0...Is there simplier way to achieve same results but don't study masterprompt's exhausting explanation which I'm not gonna be able to implement anyway. And for the second way I can't find any hints, except manual and script on unity web for bone weight, which is way too general for my use and my skills. I have spent looking for some solutions (tutorials) for hours, but google keeps popping the same topics, which are 4-8 years old...
Any advice how to choose the best way for changing armors and how to gain any knowledge about these issues? Thank You.
So what I'm doing in my projects is I duplicate my base character .blend file (rig, model) and I remove most of the mesh except for the body part that I want to make the clothing for (chest/legs). I pull it out a bit so the vertices doesn't overlap with base mesh and just save it.
Then in Unity I create a new prefab out of the model I just saved. The hierarchy of a prefab looks like this: parent game object with BoneReplacer.cs script -> child game object with skinned mesh renderer of my clothing.
Then all I have to do is just drag this prefab onto my character prefab so the target variable in this script points to my character's skinned mesh renderer.
This probably isn't the best way to do this but it works for me, maybe it will help you get your head around it and create some better solution.
Heres the BoneReplacer.cs script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BoneReplacer : MonoBehaviour
{
public GameObject target;
SkinnedMeshRenderer myRenderer;
Transform[] newBones;
SkinnedMeshRenderer targetRenderer;
Dictionary<string, Transform> boneMap = new Dictionary<string, Transform>();
void Start()
{
target = transform.parent.parent.gameObject;
targetRenderer = target.GetComponentInChildren<SkinnedMeshRenderer>();
foreach (Transform _bone in targetRenderer.bones)
{
boneMap[_bone.gameObject.name] = _bone;
}
myRenderer = gameObject.GetComponent<SkinnedMeshRenderer>();
newBones = new Transform[myRenderer.bones.Length];
for (int i = 0; i < myRenderer.bones.Length; i++)
{
GameObject _bone = myRenderer.bones[i].gameObject;
if (!boneMap.TryGetValue(_bone.name, out newBones[i]))
{
Debug.Log("Unable to map bone ~" + _bone.name + "~ to target skeleton!");
break;
}
}
myRenderer.bones = newBones;
myRenderer.rootBone = targetRenderer.rootBone;
}
}
I have two different threejs scenes and each has its own camera. I can control each camera individually with a corresponding TrackballControls instance.
Is there a reliable way to 'lock' or 'bind' these controls together, so that manipulating one causes the same camera repositioning in the other? My current approach is to add change listeners to the controls and update both cameras to either's change, but this isn't very neat as, for one, both controls can be changing at once (due to dampening).
I believe it should work if you set the matrices of the second camera to the values of the first and disable automatic matrix-updates of both cameras:
camera2.matrix = camera1.matrix;
camera2.projectionMatrix = camera1.projectionMatrix;
camera1.matrixAutoUpdate = false;
camera2.matrixAutoUpdate = false;
But now you need to update the matrix manually in your renderloop:
camera1.updateMatrix();
That call will take the values for position, rotation and scale (that have been updated by the controls) and compose them into camera1.matrix, which per assignment before is also used as the matrix for the second camera.
However, this feels a bit hacky and can lead to all sorts of weird problems. I personally would probably prefer the more explicit approach you have already implemented.
Question is why are you even using two camera- and controls-instances? As long as the camera isn't added to the scene you can just render both scenes using the same camera.
Is it possible to use the Observer or Publisher design patterns to control these objects?
It seems that you are manipulating the cameras with a control. You might create an object that has the same control interface, but when you pass a command to the object, it repeats that same command to each of the subscribed or registered cameras.
/* psuedo code : es6 */
class MasterControl {
constructor(){
this.camera_bindings = [];
}
control_action1(){
for( var camera of this.camera_bindings ){
camera.control_action1();
}
}
control_action2( arg1, arg2 ){
for( var camera of this.camera_bindings ){
camera.control_action2( arg1, arg2 );
}
}
bindCamera( camera ){
if( this.camera_bindings.indexOf( camera ) === -1 ){
this.camera_bindings.push( camera );
}
}
}
var master = new MasterControl();
master.bindCamera( camera1 );
master.bindCamera( camera2 );
master.bindCamera( camera3 );
let STEP_X = -5;
let STEP_Y = 10;
//the following command will send the command to all three cameras
master.control_action2( STEP_X, STEP_Y );
This binding is self created rather than using native three.js features, but it is easy to implement and can get you functional quickly.
Note: I wrote my psuedocode in es6, because it is simpler and easy to communicate. You can write it in es5 or older, but you must change the class definition into a series of functional object definitions that create the master object and its functionality.
I have a face detection app, and I want a character's head to rotate according to the detected face's pose.
I've managed to get the rotation of the detected face in the form of a quaternion, but I'm unsure about how I'm supposed to translate the data from the quaternion into 3D points for the reference points of the rigged character which I believe will decide the rotation.
Let's say I have this character: http://i.imgur.com/3pcRoYx.png
One solution could be to just cut off the head and make it an own object and then set the rotation of that object according to the quaternion, but I don't want that. I want an intact character.
Is it possible to move the reference points in the head with the data from a quaternion? Or have I gotten it wrong how rigged characters turn their heads? I haven't animated before.
You can apply rotation to a single bone. Get that bone in your script. Keep a var in your class to store the last quaternion in and every update, compare it to that and rotate by the different. I don't have the actual editor here but try this psuedocode.
class NeckRotator {
public GameObject Neck;
private Quaternion LastFace;
void Start(){
LastFace = Neck.transform.Rotation;
}
void Update(){
var DetectedFace = ... // Whatever you do to get this
var Change = Quaternion.Inverse(DetectedFace) * LastFace; // Found this online real quick
Neck.Rotate(Change);
LastFace = Neck.transform.Rotation;
}
}
I've done something like that before to rotate a neck of an NPC to look at a player. It should work for your deal as well.
I've got a question about libGDX collision detection. Because it's a rather specific question I have not found any good solution on the internet yet.
So, I already created "humans" that consist of different body parts, each with rectangle-shaped collision detection.
Now I want to implement weapons and skills, which for example look like this:
Skill example image
Problem
Working with rectangles in collision detections would be really frustrating for players when there are skills like this: They would dodge a skill successfully but the collision detector would still damage them.
Approach 1:
Before I started working with Libgdx I have created an Android game with a custom engine and similar skills. There I solved the problem following way:
Detect rectangle collision
Calculate overlapping rectangle section
Check every single pixel of the overlapping part of the skill for transparency
If there is any non-transparent pixel found -> Collision
That's a kind of heavy way, but as only overlapping pixels are checked and the rest of the game is really light, it works completely fine.
At the moment my skill images are loaded as "TextureRegion", where it is not possible to access single pixels.
I have found out that libGDX has a Pixmap class, which would allow such pixel checks. Problem is: having them loaded as Pixmaps additionally would 1. be even more heavy and 2. defeat the whole purpose of the Texture system.
An alternative could be to load all skills as Pixmap only. What do you think: Would this be a good way? Is it possible to draw many Pixmaps on the screen without any issues and lag?
Approach 2:
An other way would be to create Polygons with the shape of the skills and use them for the collision detection.
a)
But how would I define a Polygon shape for every single skill (there are over 150 of them)? Well after browsing a while, I found this useful tool: http://www.aurelienribon.com/blog/projects/physics-body-editor/
it allows to create Polygon shapes by hand and then save them as JSON files, readable by the libGDX application. Now here come the difficulties:
The Physics Body Editor is connected to Box2d (which I am not using). I would either have to add the whole Box2d physics engine (which I do not need at all) just because of one tiny collision detection OR I would have to write a custom BodyEditorLoader which would be a tough, complicated and time-intensive task
Some images of the same skill sprite have a big difference in their shapes (like the second skill sprite example). When working with the BodyEditor tool, I would have to not only define the shape of every single skill, but I would have to define the shape of several images (up to 12) of every single skill. That would be extremely time-intensive and a huge mess when implementing these dozens of polygon shapes
b)
If there is any smooth way to automatically generate Polygons out of images, that could be the solution. I could simply connect every sprite section to a generated polygon and check for collisions that way. There are a few problems though:
Is there any smooth tool which can generate Polygon shapes out of an image (and does not need too much time therefor)?
I don't think that a tool like this (if one exists) can directly work with Textures. It would probably need Pixmaps. It would not be needed to keep te Pixmaps loaded after the Polygon creation though. Still an extremely heavy task!
My current thoughts
I'm stuck at this point because there are several possible approaches but all of them have their difficulties. Before I choose one path and continue coding, it would be great if you could leave some of your ideas and knowledge.
There might be helpful classes and code included in libGDX that solve my problems within seconds - as I am really new at libGDX I just don't know a lot about it yet.
Currently I think I would go with approach 1: Work with pixel detection. That way I made exact collision detections possible in my previous Android game.
What do you think?
Greetings
Felix
I, personally, would feel like pixel-to-pixel collision would be overkill on performance and provide some instances where I would still feel cheated - (I got hit by the handle of the axe?)
If it were me, I would add a "Hitbox" to each skill. StreetFighter is a popular game which uses this technique. (newer versions are in 3D, but hitbox collision is still 2D) Hitboxes can change frame-by-frame along with the animation.
Empty spot here to add example images - google "Streetfighter hitbox" in the meantime
For your axe, there could be a defined rectangle hitbox along the edge of one or both ends - or even over the entire metal head of the axe.
This keeps it fairly simple, without having to mess with exact polygons, but also isn't overly performance heavy like having every single pixel being its own hitbox.
I've used that exact body editor you referenced and it has the ability to generate polygons and/or circles for you. I also made a loader for the generated JSON with the Jackson library. This may not be the answer for you since you'd have to implement box2d. But here's how how I did it anyway.
/**
* Adds all the fixtures defined in jsonPath with the name'lookupName', and
* attach them to the 'body' with the properties defined in 'fixtureDef'.
* Then converts to the proper scale with 'width'.
*
* #param body the body to attach fixtures to
* #param fixtureDef the fixture's properties
* #param jsonPath the path to the collision shapes definition file
* #param lookupName the name to find in jsonPath json file
* #param width the width of the sprite, used to scale fixtures and find origin.
* #param height the height of the sprite, used to find origin.
*/
public void addFixtures(Body body, FixtureDef fixtureDef, String jsonPath, String lookupName, float width, float height) {
JsonNode collisionShapes = null;
try {
collisionShapes = json.readTree(Gdx.files.internal(jsonPath).readString());
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
for (JsonNode node : collisionShapes.findPath("rigidBodies")) {
if (node.path("name").asText().equals(lookupName)) {
Array<PolygonShape> polyShapes = new Array<PolygonShape>();
Array<CircleShape> circleShapes = new Array<CircleShape>();
for (JsonNode polygon : node.findPath("polygons")) {
Array<Vector2> vertices = new Array<Vector2>(Vector2.class);
for (JsonNode vector : polygon) {
vertices.add(new Vector2(
(float)vector.path("x").asDouble() * width,
(float)vector.path("y").asDouble() * width)
.sub(width/2, height/2));
}
polyShapes.add(new PolygonShape());
polyShapes.peek().set(vertices.toArray());
}
for (final JsonNode circle : node.findPath("circles")) {
circleShapes.add(new CircleShape());
circleShapes.peek().setPosition(new Vector2(
(float)circle.path("cx").asDouble() * width,
(float)circle.path("cy").asDouble() * width)
.sub(width/2, height/2));
circleShapes.peek().setRadius((float)circle.path("r").asDouble() * width);
}
for (PolygonShape shape : polyShapes) {
Vector2 vectors[] = new Vector2[shape.getVertexCount()];
for (int i = 0; i < shape.getVertexCount(); i++) {
vectors[i] = new Vector2();
shape.getVertex(i, vectors[i]);
}
shape.set(vectors);
fixtureDef.shape = shape;
body.createFixture(fixtureDef);
}
for (CircleShape shape : circleShapes) {
fixtureDef.shape = shape;
body.createFixture(fixtureDef);
}
}
}
}
And I would call it like this:
physics.addFixtures(body, fixtureDef, "ship/collision_shapes.json", shipType, width, height);
Then for collision detection:
public ContactListener shipsExplode() {
ContactListener listener = new ContactListener() {
#Override
public void beginContact(Contact contact) {
Body bodyA = contact.getFixtureA().getBody();
Body bodyB = contact.getFixtureB().getBody();
for (Ship ship : ships) {
if (ship.body == bodyA) {
ship.setExplode();
}
if (ship.body == bodyB) {
ship.setExplode();
}
}
}
};
return listener;
}
then you would add the listener to the world:
world.setContactListener(physics.shipsExplode());
my sprites' width and height were small since you're dealing in meters not pixels once you start using box2d. One sprite height was 0.8f and width was 1.2f for example. If you made the sprites width and height in pixels the physics engine hits speed limits that are built in http://www.iforce2d.net/b2dtut/gotchas
Don't know if this still matter to you guys, but I built a small python script that returns the pixels positions of the points in the edges of the image. There is room to improve the script, but for me, for now its ok...
from PIL import Image, ImageFilter
filename = "dship1"
image = Image.open(filename + ".png")
image = image.filter(ImageFilter.FIND_EDGES)
image.save(filename + "_edge.png")
cols = image.width
rows = image.height
points = []
w = 1
h = 1
i = 0
for pixel in list(image.getdata()):
if pixel[3] > 0:
points.append((w, h))
if i == cols:
w = 0
i = 0
h += 1
w += 1
i += 1
with open(filename + "_points.txt", "wb") as nf:
nf.write(',\n'.join('%s, %s' % x for x in points))
In case of updates you can find them here: export positions
I have a character made of up child objects that are animated using Unity3D's animation system.
While the player is walking, I can programmatically move the hand object up to catch a ball using the following code.
hand.position.y = ball.transform.position.y;
I need the hand object to go back to following the walk animation after it touches the ball, but instead it just stays at the exact position since it was set.
You want to use inverse kinematics and let Unity do the work of figuring out positioning for you. Here's a quick-and-dirty (untested) example for catching a ball (it's in C#, but it should be pretty similar for UnityScript):
// in a script on the same GameObject as your animation controller
bool isCatching;
Transform ball;
void OnAnimatorIK (int layer) {
if (isCatching) {
// set position and rotation weights for your catching hand
animator.SetIKPosition(AvatarIKGoal.RightHand, ball.position);
animator.SetIKRotation(AvatarIKGoal.RightHand, ball.rotation);
} else {
// return your position and rotation weights back to their defaults (probably 0f?)
}
}
You'll need to do some work (possibly raycasting or just checking distance and direction) to determine when to set the isCatching flag to true, and you'll want to play with the weights for position and rotation to make it look natural. The IK manual entry has more detailed information.