Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
DStecks
Feb 6, 2012

Fano posted:

Shouldn't you be returning true at the end of the function? What is "walkable" assigned to?

walkable is a boolean assigned from the inspector, it's set to false for tiles which are never, ever walkable.

xgalaxy posted:

I don't believe you. Your code looks correct but the transform you give to Sphere looks fishy based on your explanation.

I'll have to double-check the coordinates then. Unfortunately I don't have any time before I have to go to work. If it's useful, here's the entirety of my pathfinding method:

code:
public static bool findPath(Actor a, NavTile n, ref List<NavTile> path)
    {
        //Load the level map info
        GameObject mapSource = GameObject.Find("GameController");
        NavTile[,] map = mapSource.GetComponent<EncounterController>().LevelMap.contents;

        // Create the open and closed lists for nodes
        List<NavTile> closedList = new List<NavTile>();
        List<NavTile> openList = new List<NavTile>();

        // Create the "currentNode" for use when assigning parent nodes during the search. It will automatically be filled with the starting node.
        NavTile currentNode = new NavTile();
        currentNode = map[a.navMapX, a.navMapY];
        NavTile checkNode = new NavTile();

        //Start by adding the starting tile to the open list. We get the starting tile by checking the map for the tile with the same coords as the actor passed.
        openList.Add(currentNode);
        int loopKiller = 0;

        do
        {
            ++loopKiller;

            //Search openList for tile with lowest F score.
            openList.Sort(NavTile.TilePathingCost);
            currentNode = openList[0];

            // Loop which checks adjacent sqaures and adds them to the open list.
            for (int x = 0; x < 3; ++x)
            {
                for (int y = 0; y < 3; ++y)
                {
                    //Set the checked node. This is just to make the code more readable.
                    checkNode = map[((currentNode.MapX - 1) + x), ((currentNode.MapY - 1) + y)];

                    //Checks the 8 adjacent squares. 
                    if (closedList.Contains(checkNode) != true && checkNode != currentNode && checkNode.isNavigable(currentNode))
                    {
                        // Checks if the checked tile is already on the open list, and if so, see if the new route is cheaper than the old one.
                        if (openList.Contains(checkNode))
                        {
                            //Find directionality cost for moving to the new tile. 
                            int directionality;
                            // If the X or Y values are the same as the current node, it is an orthogonal move. If both are different, the move is diagonal.
                            if (checkNode.MapX == currentNode.MapX || checkNode.MapY == currentNode.MapY)
                            {
                                directionality = 10 + currentNode.G; //Ten is used as standard travel cost.
                            }
                            else
                            {
                                directionality = 14 + currentNode.G; //14 is diagonal travel cost, a simplification of the square root of 2.
                            }

                            // If the new route to this node is cheaper, set the new G cost and set the currentTile as its new parent.
                            if (checkNode.G > currentNode.G + directionality)
                            {
                                checkNode.G = currentNode.G + directionality;
                                checkNode.parent = currentNode;
                                //Set the F cost for each tile; the combined G and H costs.
                                checkNode.F = checkNode.H + checkNode.G;
                            }

                        }
                        else
                        {
                            openList.Add(checkNode);

                            // If the X or Y values are the same as the current node, it is an orthogonal move. If both are different, the move is diagonal.
                            if (checkNode.MapX == currentNode.MapX || checkNode.MapY == currentNode.MapY)
                            {
                                checkNode.G = 10 + currentNode.G; //Ten is used as standard travel cost.
                            }
                            else
                            {
                                checkNode.G = 14 + currentNode.G; //14 is diagonal travel cost, a simplification of the square root of 2.
                            }

                            //Set the current node as each of these tiles' parent.
                            checkNode.parent = currentNode;

                            //Set the H cost for each tile; the estimated distance to the target.
                            checkNode.H = (Mathf.Abs(n.MapX - checkNode.MapX) + Mathf.Abs(n.MapY - checkNode.MapY)) * 10;

                            //Set the F cost for each tile; the combined G and H costs.
                            checkNode.F = checkNode.H + checkNode.G;
                        }

                    }
                }

            }

            //Drop the current node from the open list, then add it to the closed list, since all of its adjacencies have been checked.
            openList.Remove(currentNode);
            closedList.Add(currentNode);

            if (currentNode == n)
            {
                Debug.Log("Found the target!!!");
            }

            if (loopKiller > 1000)
            {
                Debug.Log("Had to kill the loop.");
                break;
            }
        } while (currentNode != n);

        //TESTING: Print out openList, I want to see that this is even working.
        for (int i = 0; i < openList.Count; ++i)
        {
            //Debug.Log("Tile " + openList[i].ToString() + " is on the open list");
        }
        Debug.Log("There are " + openList.Count + " tiles on the open list.");

        for (int i = 0; i < closedList.Count; ++i)
        {
            //Debug.Log("Tile " + closedList[i].ToString() + " is on the closed list");
        }
        Debug.Log("There are " + closedList.Count + " tiles on the closed list.");

        // Assemble the pathfinding route based on the parents of the tiles, starting from the end.
        List<NavTile> route = new List<NavTile>();

        route.Add(n);
        int iterator = 0;
        while (route[iterator].parent != null)
        {
            route.Add(route[iterator].parent);
            ++iterator;
            if (iterator > 100)
            {
                Debug.Log("WOOPS! Had to kill the route-creating loop.");
                break;
            }
        }

        //Reverse the list, so the pathfinding is in forward order.
        route.Reverse();
        
        //Check if the found route is less than the actor's remaining TUs.
        if(route[route.Count - 1].F <= a.timeUnits)
        {
            //Clear parent information from the open and closed lists, so consecutive pathfinding works.
            for (int i = 0; i < openList.Count; ++i)
            {
                openList[i].parent = null;
                openList[i].G = 0;
                openList[i].F = 0;
                openList[i].H = 0;
            }
            for (int i = 0; i < closedList.Count; ++i)
            {
                closedList[i].parent = null;
                closedList[i].G = 0;
                closedList[i].F = 0;
                closedList[i].H = 0;
            }

            path = route;
            Debug.Log("Good route found!" + " Path is " + path.Count +" long.");
            return true;
            
        }
        else
        {
            //Clear parent information from the open and closed lists, so consecutive pathfinding works.
            for (int i = 0; i < openList.Count; ++i)
            {
                openList[i].parent = null;
                openList[i].G = 0;
                openList[i].F = 0;
                openList[i].H = 0;
            }
            for (int i = 0; i < closedList.Count; ++i)
            {
                closedList[i].parent = null;
                closedList[i].G = 0;
                closedList[i].F = 0;
                closedList[i].H = 0;
            }

            Debug.Log("No route found!");
            return false;
        }
    }

Adbot
ADBOT LOVES YOU

DStecks
Feb 6, 2012

Figured it out: I was using transform.localPosition when I should have been using transform.position. I'd always been using localposition, and it had been working, but all of my map tiles are parented to a gameobject for keeping them together, so that was what screwed me up.

emanresu tnuocca
Sep 2, 2011

by Athanatos
Is there a thread for basic OpenGL related questions? I struggle with some very basic poo poo.

I have this 2d game, all of my objects are 2d polygons that exist on the xy plane, when I use orthographic projection with glOrtho everything works well:
code:
		int halfWidth = this.getWidth() / 2;
		int halfHeight = this.getHeight() / 2;
		gl.glMatrixMode(GL2.GL_PROJECTION);
		// initialize the matrix
		gl.glLoadIdentity();
		// initialize the matrix (0,0) is in the center of the window
		gl.glOrtho(-halfWidth + main.getCamera().getOffsetX(), halfWidth + main.getCamera().getOffsetX(), -halfHeight + main.getCamera().getOffsetY(), halfHeight + main.getCamera().getOffsetY(), 0, 1);
Oh yeah I'm using JAVA JOGL bindings, but the OpenGL code should mostly be identical I suppose.

but now if I try to comment out gl.glOrtho and try to use regular perspective projection just moving the camera a bit back on the Z axis so that it would point at the exact same plane (only without the orthographic projection) I all of a sudden don't see anything at all, I tried at first simply using gl.gltranslatef(0.0f,0.0f, -6.0f) and it doesn't work, then I tried using gluPerspective, same results... I figured my camera might be pointing in the wrong direction but then when I used glu.glulookat(0,0,-6,0,0,0,0,0,-1) - that is camera at 0,0,-6 looking at 0,0,0 pointing towards the negative Z direction - I still can't see anything.

I'm really quite confused cause this should be rather trivial, if I can see the painted vertices projected orthographically why can't I see them with non-orthographic projection just pointing toward the plane the vertices are on?

I can share my code if anyone would fancy taking a look, alternatively I'd also appreciate recommendations for solid articles\tutorials\books about OpenGL and using projections, I'm just very confused about this whole thing.

SupSuper
Apr 8, 2009

At the Heart of the city is an Alien horror, so vile and so powerful that not even death can claim it.

emanresu tnuocca posted:

Is there a thread for basic OpenGL related questions? I struggle with some very basic poo poo.
The first things I'd check are common culling problems:

- Even though your stuff is 2D, you need to make sure they are within the perspective camera's near and far plane (z axis)

- Also make sure the camera is pointed at the front side and not the back side.

Polio Vax Scene
Apr 5, 2009



I would think you would want your up vector to be on the Y axis if you're offsetting the camera on the Z axis. Try glu.glulookat(0,0,-6,0,0,0,0,-1,0)

Sex Bumbo
Aug 14, 2004

emanresu tnuocca posted:

Is there a thread for basic OpenGL related questions? I struggle with some very basic poo poo.

there's this
http://forums.somethingawful.com/showthread.php?threadid=2897255

If it renders with an orthographic projection it's almost certainly your perspective projection parameters which you didn't post.

Manslaughter posted:

I would think you would want your up vector to be on the Y axis if you're offsetting the camera on the Z axis. Try glu.glulookat(0,0,-6,0,0,0,0,-1,0)
E: or this, yeah.

Sex Bumbo fucked around with this message at 21:13 on Oct 4, 2015

emanresu tnuocca
Sep 2, 2011

by Athanatos
Yeah I had to switch the up vector to the y axis as you guys said, and I was also looking at the projection from below which wasn't good, and on top of that I had a method I used to zoom out of the orthographic projection that was still doing its thing in the background that was messing things up.

So yeah, that's pretty cool. Thanks for the help.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Is there a simple way to handle some polymorphism with a component in Unity? I want to have a component provide an implementation of an interface for being interacted with by the environment. The interactions are basically "use key" kind of things: opening doors, opening chests, and hitting a button. I'd like to attach code to these objects to behave different when this stuff happens. How might I do that cleanly?

As it stands, I have a MonoBehavior that just contains an instance of my interface for world interaction. I then have components for this or that interaction that implement the interface. I have to remember in the Start() method for them to look up the component that contains the generic interface and replace that with a reference to the this component. Then things that want to perform a use on the environment don't need to know what exactly they're interacting with, so long as the object has the component that exposes world interaction. It just seems very fragile.

supermikhail
Nov 17, 2012


"It's video games, Scully."
Video games?"
"He enlists the help of strangers to make his perfect video game. When he gets bored of an idea, he murders them and moves on to the next, learning nothing in the process."
"Hmm... interesting."
How to make sprites? I think I should start working on graphics for my game, but I'm kind of terrified of any method because of my lack of experience and that it's going to take an unbearable amount of time. I started out thinking that I'd render stuff in Blender, but now that I should actually get down to it I'm realizing that in the past I've taken months to create a relatively simple model. The thing is, out of all kinds of art I've tried, my Blender models have been the most aesthetically appealing, I think (although the adjective "lovely" would certainly be applicable), and there's certain advantages if you've never done traditional animation.

emanresu tnuocca
Sep 2, 2011

by Athanatos

Rocko Bonaparte posted:

Is there a simple way to handle some polymorphism with a component in Unity? I want to have a component provide an implementation of an interface for being interacted with by the environment. The interactions are basically "use key" kind of things: opening doors, opening chests, and hitting a button. I'd like to attach code to these objects to behave different when this stuff happens. How might I do that cleanly?

As it stands, I have a MonoBehavior that just contains an instance of my interface for world interaction. I then have components for this or that interaction that implement the interface. I have to remember in the Start() method for them to look up the component that contains the generic interface and replace that with a reference to the this component. Then things that want to perform a use on the environment don't need to know what exactly they're interacting with, so long as the object has the component that exposes world interaction. It just seems very fragile.

(Again with the caveat that I don't actually use unity)

When you implement an interface this indicates to whichever collection of objects that might reference an object that this object can perform certain actions, say, if you have a "hasLock" interface and an "openable" interface and you have a door object implementing both interfaces it's gonna look something like this:

code:
 
public interface hasLock
{
    void unlock(KeyObject key);
}

public interface openable 
{
   void open();
}

//note that interfaces don't actually implement any functionality themselves, they only indicate that any object implementing said interface will implement the specified methods.
// so now we have a door object

public class door extends MonoBehavior implements hasLock, openable
{
// ... door fields methods etc
// since the door implements both interfaces you'll get a note from the IDE telling you you must add the unimplemented methods, so we implement them

void unlock(KeyObject key)
{
// some key logic I presume
if(this.getLock().getKey().equals(key))
     this.locked = false;
}
}

void open()
{
if (locked == false)
// ... open door logic etc

}

}
}
Now, if you have some other object that has keys and the ability to interact with openable objects, when you encounter the door you only have to check that the object you're interacting with implements said interfaces, to my understanding the syntax is unity script is simply:
code:
if(someObject is openable)
{
someObject.open() // you might need to cast this object so that the compiler will know it implements openable
}
Basically as you would use an interface in any other object oriented language? Polymorphism is sorta implied when using interfaces cause as mentioned, Interfaces themselves do not contain any implementation of the methods they specify.
https://unity3d.com/learn/tutorials/modules/intermediate/scripting/interfaces

Apologies if I misunderstood your question and my answer is referring to some basic poo poo you already knew.

xgalaxy
Jan 27, 2004
i write code
GameObjects can't be extended and can't implement interfaces though. So you would have to do something like GetAllComponents on a gameObject and then traverse that component list to get all of the components that implemented openable. You could wrap this in an extension method to GameObject though.

The function you are looking for would be:
code:
gameObject.GetComponents(typeof(IOpenable));
So your extension method could be:
code:
public static bool TryGetOpenable(this GameObject go, out IOpenable openable)
{
	var component = go.GetComponent(typeof(IOpenable));
        if (component == null)
		return false;

	openable = component;
	return true;
}

// how you use it
IOpenable openable = null;
if (gameObject.TryGetOpenable(out openable))
{
	openable.Open();
	// do stuff...
}

xgalaxy fucked around with this message at 16:23 on Oct 5, 2015

Polio Vax Scene
Apr 5, 2009



supermikhail posted:

How to make sprites? I think I should start working on graphics for my game, but I'm kind of terrified of any method because of my lack of experience and that it's going to take an unbearable amount of time. I started out thinking that I'd render stuff in Blender, but now that I should actually get down to it I'm realizing that in the past I've taken months to create a relatively simple model. The thing is, out of all kinds of art I've tried, my Blender models have been the most aesthetically appealing, I think (although the adjective "lovely" would certainly be applicable), and there's certain advantages if you've never done traditional animation.

Spriting takes more time and effort than everything else combined. Offload that crap to someone else!

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

xgalaxy posted:

GameObjects can't be extended and can't implement interfaces though. So you would have to do something like GetAllComponents on a gameObject and then traverse that component list to get all of the components that implemented openable. You could wrap this in an extension method to GameObject though.

The function you are looking for would be:
code:
gameObject.GetComponents(typeof(IOpenable));
So your extension method could be:
I was going to say how surprised I was that I could just cast the game object to the interface. That would have to be some Mono voodoo. I was going to try it tonight just to see, but this sounds more like reality. Extension methods always leave me initially sour, but I think this is less likely for me to screw up when implementing multiple instances of the interface for all the different things.

poemdexter
Feb 18, 2005

Hooray Indie Games!

College Slice
Why not have an Openable component and attach that to everything that needs to be opened?

I feel like you're not embracing the Entity/Component pattern and trying to force everything to be strict OOP.

orenronen
Nov 7, 2008

Rocko Bonaparte posted:

I was going to say how surprised I was that I could just cast the game object to the interface. That would have to be some Mono voodoo. I was going to try it tonight just to see, but this sounds more like reality. Extension methods always leave me initially sour, but I think this is less likely for me to screw up when implementing multiple instances of the interface for all the different things.

You can also use inheritance from an abstract class instead of interfaces, which tend to work better with Unity's newer generics-based API. gameObject.GetComponent<MyAbstractClass>() will get you any component that inherits from that class, with virtual functions functioning as you would expect.

FuzzySlippers
Feb 6, 2009

orenronen posted:

You can also use inheritance from an abstract class instead of interfaces, which tend to work better with Unity's newer generics-based API. gameObject.GetComponent<MyAbstractClass>() will get you any component that inherits from that class, with virtual functions functioning as you would expect.

GetComponent<IWhateverClass>() does the exact same thing with interfaces. I use it a lot. It uses to work differently but they updated it sometime in late 4.x from what used to be an undocumented feature for the other GetComponent.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

poemdexter posted:

Why not have an Openable component and attach that to everything that needs to be opened?

I feel like you're not embracing the Entity/Component pattern and trying to force everything to be strict OOP.

I'm in a strange gray area in the design right here. The issue is when the player wants to interact with the environment, I don't want to have to code for every possibility right there in the player control code. The possibilities are ultimately going to be finite, so I could just suck it up and test for all of them, but I'd rather just scan all the game objects in the use area, see if they are capable of being interacted with, and then just tell them to be interacted with the player. This without knowing exactly what the interaction might be. So I figured an interface would give me that disassociation, but I can't figure out then how to tie it to a component that states it's capable of being interacted with this way.

FuzzySlippers posted:

GetComponent<IWhateverClass>() does the exact same thing with interfaces. I use it a lot. It uses to work differently but they updated it sometime in late 4.x from what used to be an undocumented feature for the other GetComponent.

I have 4.6.8f1 and this doesn't seem to compile. It's complaining I can't cast my IWorldInteractable to UnityEngine.Component.

Here's what I'm doing:
code:
                    // Bare-handed use.  Perform environment interaction.
                    var usePosition = gameObject.transform.position + 1.0f * gameObject.transform.forward;
                    var colliders = Physics.OverlapSphere(usePosition, 1.0f);
                    for (int i = 0; i < colliders.Length; ++i)
                    {
                        // Let's not play with ourselves, kids!
                        if (colliders[i].gameObject != gameObject)
                        {
                            Debug.Log("Collided with " + colliders[i].gameObject);
                            var interactor = colliders[i].gameObject.GetComponent<IWorldInteractable>();    // *** Sad Error here
                            if(interactor != null)
                            {
                                interactor.InteractWith(gameObject);
                            }
                        }
                    }

orenronen
Nov 7, 2008

FuzzySlippers posted:

GetComponent<IWhateverClass>() does the exact same thing with interfaces. I use it a lot. It uses to work differently but they updated it sometime in late 4.x from what used to be an undocumented feature for the other GetComponent.

Huh, I just tested it in 5.1 and it does indeed work. I know for a fact it didn't used to, so I probably just missed the fix along the way.

Still, querying for classes up the inheritance tree have always worked, and it may even be the better solution if you want to implement some default behavior.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
The 4.6 release notes state:

quote:

Added smart-allocating GetComponents<List> method which fetches components of type T and grows the list as needed. Non-generic version that supports interfaces has also been added.
So there's apparently one version of this in some form that works. I haven't managed to figure it out yet.

Edit: Oh the non-generic version! Literacy!

code:
var interactors = colliders[i].gameObject.GetComponents(typeof(IWorldInteractable));

// Remember, foreach is the devil in Unity's Mono!
for(int interact_i = 0; interact_i < interactors.Length; ++interact_i)
{
   ((IWorldInteractable)interactors[interact_i]).InteractWith(gameObject);
}

Rocko Bonaparte fucked around with this message at 02:23 on Oct 6, 2015

orenronen
Nov 7, 2008

Rocko Bonaparte posted:

code:
// Remember, foreach is the devil in Unity's Mono!

Incidentally, I think this is made a much bigger deal than it actually is. foreach is perfectly fine unless you're calling it thousands of times in an inner loop or something - our code (for a decently sized game) uses it quite a bit, even in Update methods, and performs perfectly well on years old mobile devices.

I say use foreach and LINQ and the other stuff Unity programmers like to warn against. If you're responsible in your coding and know what can actually go wrong with them they're amazing for code clarity and simpleness.

FuzzySlippers
Feb 6, 2009

orenronen posted:

Huh, I just tested it in 5.1 and it does indeed work. I know for a fact it didn't used to, so I probably just missed the fix along the way.

Still, querying for classes up the inheritance tree have always worked, and it may even be the better solution if you want to implement some default behavior.

Definitely for some things, but like lately I've been dealing with a bunch of different objects you can click on in a world space map. Since the objects are otherwise unrelated it makes sense to me to have an IMapClickable interface that anything can implement and respond to. I'm glad using interfaces has been improved as I think the "Unity way" for this kind of problem previously used to be to use SendMessage (which I hate) or have a clicker monobehaviour you attach to everything and interfaces can be a lot simpler implementation.

Presumably somebody at Unity works there now who's really on the interface bandwagon since all the new UI stuff works through interfaces so they added more functionality for using them.

FuzzySlippers fucked around with this message at 02:59 on Oct 6, 2015

xgalaxy
Jan 27, 2004
i write code

orenronen posted:

Incidentally, I think this is made a much bigger deal than it actually is. foreach is perfectly fine unless you're calling it thousands of times in an inner loop or something - our code (for a decently sized game) uses it quite a bit, even in Update methods, and performs perfectly well on years old mobile devices.

I say use foreach and LINQ and the other stuff Unity programmers like to warn against. If you're responsible in your coding and know what can actually go wrong with them they're amazing for code clarity and simpleness.

Its best to avoid LINQ if you are targeting an AOT only device, such as iOS. While there are large portions of LINQ that are perfectly fine on mobile, there are other parts that are not and will throw runtime exceptions on the device and it is often hard to track down where the error is coming in after the fact.

I'm not sure if IL2CPP changes this at all or not, and AOT errors in general. Anyone know? My guess is that since IL2CPP is just another form of AOT compilation that it is going to have the same limitations and that LINQ still won't 100% function. Anyways, if you really want to use LINQ than use either this or this.

I agree with you about the foreach situation though. Best to just use foreach and only change loops that you actually find to be a problem and then only after profiling it.

xgalaxy fucked around with this message at 06:36 on Oct 6, 2015

orenronen
Nov 7, 2008

xgalaxy posted:

Its best to avoid LINQ if you are targeting an AOT only device, such as iOS. While there are large portions of LINQ that are perfectly fine on mobile, there are other parts that are not and will throw runtime exceptions on the device and it is often hard to track down where the error is coming in after the fact.

Our game is mobile for both iOS and Android and we're using LINQ (as well as stuff like Reactive Extensions) heavily. Just like with foreach, as long as you actually understand what the potential problems are and why they're there, they're very easy to avoid.

il2cpp doesn't solve any of it - the code it generates is still equivalent to AOT.

xgalaxy
Jan 27, 2004
i write code

orenronen posted:

Our game is mobile for both iOS and Android and we're using LINQ (as well as stuff like Reactive Extensions) heavily. Just like with foreach, as long as you actually understand what the potential problems are and why they're there, they're very easy to avoid.

il2cpp doesn't solve any of it - the code it generates is still equivalent to AOT.

Can't help but feel that this is easier said than is actually witnessed in practice. Is there a list online somewhere that details which parts of LINQ will have potential problems and under what circumstances? In the past I've used parts of LINQ that seemed perfectly fine with some set of types and then blew up with AOT runtime exceptions on other types. Oh that type didn't specify a default IEqualityComparable, sorry - have an AOT exception.

DStecks
Feb 6, 2012

I'm trying to do stuff with instantiating prefabs in Unity; is there a way to create a local copy of a GameObject and make modifications to it before instantiating the local copy? Because if I just write "GameObject newFromPrefab = prefabObject", making modifications to newFromPrefab carries those modifications over to the prefab.

EDIT: figured it out.

DStecks fucked around with this message at 18:58 on Oct 6, 2015

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Does anybody have an existing, nice little angle calculation helper? I'm dealing with shenanigans like testing if something is rotated to -90 degrees, and finding out instead it's rotated to 270 degrees. I'm scribbling it as a I go, but I am willing to shamelessly draw upon some helper code if there is some.

Tann
Apr 1, 2009

Rocko Bonaparte posted:

Does anybody have an existing, nice little angle calculation helper? I'm dealing with shenanigans like testing if something is rotated to -90 degrees, and finding out instead it's rotated to 270 degrees. I'm scribbling it as a I go, but I am willing to shamelessly draw upon some helper code if there is some.

I struggle with this every single time it comes up haha

Telarra
Oct 9, 2012

Looks like a job for the modulus operator:
code:
angle % 360 == target_angle
Though apparently every language has a different opinion on how to handle negative arguments for modulus, so you can throw an abs() in there to fix it if necessary.

So for Unity:
C# code:
Mathf.Abs(angle % 360) == target_angle
e: Of course, if target_angle isn't a hardcoded value you'll have to modulus+abs it as well.

Telarra fucked around with this message at 01:54 on Oct 8, 2015

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I'm talking more than modulus. Like, I wanted to tell when some rotation is within 2 degrees of another rotation. And then there's shenanigans with wrapping 0 degrees and 360 degrees. Also, finding the shortest distance between two angles. There's just lots of stupid little things that I don't image are really worth coding over again.

Tann
Apr 1, 2009

The thing that gets me is trying to interpolate smoothly between two angles. Takes me forever to get it to always rotate the shortest way.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Moddington posted:

So for Unity:
C# code:
Mathf.Abs(angle % 360) == target_angle
That's not right.
Put -50 in there, you risk getting (if the modulus is one that doesn't mind returning negatives) 50 rather than the expected 310.

What generally works (caveat; can break if direction changes are >360 in one rotation) is (angle+360)%360.
To also be immune to the caveat, you could do ((angle%360)+360)%360.

Then for angle comparisons you can do something like:
code:
float normalizeAngle(float angle) {
  return ((angle%360)+360)%360;
}

float angleCompare(float a1, float a2) {
  float diff = normalizeAngle(a1) - normalizeAngle(a2);
  if (diff>180) return diff-360;
  if (diff<-180) return diff+360;
  return diff;
}
To see if two angles are within 2 degrees you'd do abs(angleCompare(a1, a2)) < 2.0

This is not optimized though.

ApproachingInfinity
Sep 14, 2008
If you're using Unity, and you're trying to find the difference between two rotated objects, you could use Quaternion.Angle on their rotations. If you have Vector2s or Vector3s there's Angle functions for both of those too; all of these will give the shortest angle between the two rotations/vectors.

Ranzear
Jul 25, 2013

It's 4:30am and I just finished a thing in three weeks.

It only looks right in Chrome, because Firefox doesn't understand using more than one canvas.

There isn't a lick of balance on anything yet.

You'll have to go dig into the types file to learn what poo poo does.

Sounds will go in over the weekend. I think I still have to do the dirty left-right hack for panning.

http://caliber.online

:getin:

ZombieApostate
Mar 13, 2011
Sorry, I didn't read your post.

I'm too busy replying to what I wish you said

:allears:

Ranzear posted:

It's 4:30am and I just finished a thing in three weeks.

It only looks right in Chrome, because Firefox doesn't understand using more than one canvas.

There isn't a lick of balance on anything yet.

You'll have to go dig into the types file to learn what poo poo does.

Sounds will go in over the weekend. I think I still have to do the dirty left-right hack for panning.

http://caliber.online

:getin:

So ramming is apparently pretty effective? If by effective, I mean your health bars both expand until they're off the screen :v:

Also, the LC model seems to have issues with actually firing. If you don't shoot the whole burst it takes forever to reload/recharge/whatever, it seems like, and you can't finish shooting off the rest of that burst.

ZombieApostate fucked around with this message at 13:11 on Oct 8, 2015

emanresu tnuocca
Sep 2, 2011

by Athanatos
Isn't it generally a lot better to work with radians rather than angles? All of the trig functions in most languages expect values to be in radians anyway and it's just something you got to get used to.


Ranzear posted:

It's 4:30am and I just finished a thing in three weeks.

It only looks right in Chrome, because Firefox doesn't understand using more than one canvas.

There isn't a lick of balance on anything yet.

You'll have to go dig into the types file to learn what poo poo does.

Sounds will go in over the weekend. I think I still have to do the dirty left-right hack for panning.

http://caliber.online

:getin:

That's pretty cool, my feedback is that it's initially a little bit confusing to figure out which way your tank is pointing towards as it is all a solid color and the turret can rotate, would be nice to have an intuitive way to always figure out your orientation (even it's just a slightly different color on the 'front' of the tank).

Tres Burritos
Sep 3, 2009

Ranzear posted:

It's 4:30am and I just finished a thing in three weeks.

It only looks right in Chrome, because Firefox doesn't understand using more than one canvas.

There isn't a lick of balance on anything yet.

You'll have to go dig into the types file to learn what poo poo does.

Sounds will go in over the weekend. I think I still have to do the dirty left-right hack for panning.

http://caliber.online

:getin:

chrome Version 45.0.2454.101 m posted:

WebSocket connection to 'ws://caliber.online/' failed: Error during WebSocket handshake: Unexpected response code: 200

:shrug:

edit: Maybe it's because I'm at work?

Tres Burritos fucked around with this message at 13:17 on Oct 8, 2015

Ranzear
Jul 25, 2013

ZombieApostate posted:

So ramming is apparently pretty effective? If by effective, I mean your health bars both expand until they're off the screen :v:

Also, the LC model seems to have issues with actually firing. If you don't shoot the whole burst it takes forever to reload/recharge/whatever, it seems like, and you can't finish shooting off the rest of that burst.

There is indeed collision damage, but I have no idea why it'd be healing tanks nor why the damage function wouldn't be keeping it positive...

There's supposed to be a partial cooldown reset on a canceled burst.

Also, you can totally shoot down missiles with bullets (but not shells). You would have trounced me with LC vs HK.

Edit: Ramming fixed. Burst reload is scaled in a better manner.

code:
if (adjdam <= 1 && pen > 0)
		adjdam = 1;
'penetration' of collision damage is 0, hence why tanks under the requisite size aren't getting pulled back to positive damage due to the 'and'. Fixed now, and all damage is minimum 1 again.

Ranzear fucked around with this message at 13:33 on Oct 8, 2015

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe

Rocko Bonaparte posted:

I'm talking more than modulus. Like, I wanted to tell when some rotation is within 2 degrees of another rotation. And then there's shenanigans with wrapping 0 degrees and 360 degrees. Also, finding the shortest distance between two angles. There's just lots of stupid little things that I don't image are really worth coding over again.

I may be misunderstanding what you're trying to do, but if you have two direction vectors can't you just dot the two and compare them with cos(angleToCompare)? Dotting should give you the cosine of the smallest possible angle between the two, and in most (if not all) implementations cos() gives you a value between -1 (for an angle of 180 degrees or pi radians) and 1 (for an angle of 0 radians/degrees.) If you have two rotations, then apply them to any unit vector (e.g. vec3(1,0,0)) and do the comparison between those two.

E: Mix up on acos and cos.

Joda fucked around with this message at 13:39 on Oct 8, 2015

ZombieApostate
Mar 13, 2011
Sorry, I didn't read your post.

I'm too busy replying to what I wish you said

:allears:
I still got stuck where I couldn't shoot anymore with the LC and I think you saw what happened when ramming :v:

Maybe the shooting problem has something to do with trying to shoot before the recharge is finished?

Adbot
ADBOT LOVES YOU

Ranzear
Jul 25, 2013

ZombieApostate posted:

I still got stuck where I couldn't shoot anymore with the LC and I think you saw what happened when ramming :v:

Maybe the shooting problem has something to do with trying to shoot before the recharge is finished?

It fires in a burst of five, and now just refunds a proportion of the (really long) cooldown based on how many you didn't fire.

Time for more armor on LC, and Harasser's damage was pathetic (I think it hadn't been touched since armor values all got roughly doubled).

The minelayer might be the gooniest tank...

Ranzear fucked around with this message at 14:02 on Oct 8, 2015

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply