Announcement

Collapse
No announcement yet.

Making a Radar using scaleform..

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Making a Radar using scaleform..

    Hi...
    I'm trying to make a Radar that show pawns location using scaleform.. Others like hp bar, timer, etc..All working except the "MINIMAP"
    Here is my scaleform...
    The blue dot (pawn location) will move around on the ring (Yellow line)..
    Based on my research on UTGame minimap, they using canvas to draw the dots (location) on the minimap (Correct me if I my research are wrong)
    I would like to ask, can scaleform do like canvas??
    Only when the pawn is there, then scaleform will show the dots.. If possible to do so, what should I do on the scaleform (flash)

    I know how to calculate the range between pawn A and pawn B, but how I can get the degree of pawn A (facing direction) to to pawn B ??

    Picture will upload later....
    Thanks....

    #2
    http://1drv.ms/1m07T2W

    here is the photos that show the UI and some stuff...

    Tell me If I post at the wrong thread...

    Thanks~

    Comment


      #3
      I don't have much experience with Flash/Scaleform and communicating with it through US so code related to the movieclips may be inaccurate. I hope this is of some help though.

      First, you'd need a new instance of the blue dot movieclip for each pawn you want to show on your radar.
      Next, calculate the positional difference of the target pawns in relation to the player. From your text I think you just want the 2D location so you can ignore the Z-axis.
      -> On the other hand, you could use the Z-axis info to do something like this (pseudo-code):
      Code:
      if(Z > maxHeightDiffThreshold)
      {
          movieclip = RadarMC.AttachMovie("UpTriangleMC", "upTriangleInstanceX"); //instance name must be unique
      }
      else if(Z < -maxHeightDiffThreshold)
      {
          movieclip = RadarMC.AttachMovie("DownTriangleMC", "downTriangleInstanceX");
      }
      else //-maxHeightDiffThreshold < Z <= maxHeightDiffThreshold
      {
          movieclip = RadarMC.AttachMovie("DotMC", "dotInstanceX");
      }
      -> You could also do some fun things with the size or 'magnitude' of the vector; ie the bigger the magnitude, the more transparent the dot.

      Now, the following would depend on how you set up your dot movieclip.
      - If your movieclip is just the dot itself, you need to translate the X/Y-axis positional difference into screen coordinates. Just make sure it's anchored to the center of the MC.
      You probably want to use a normalized vector and multiply that by the distance of the movieclip to the center of the HUD. This would be the location of the movieclip within your HUD.
      Pseudo-code:
      Code:
      //Either clean all movieclip instances or re-use existing and only remove/add movieclips as needed.
      foreach (otherPawn within range) //Assuming you only want to show enemies within a certain range.
      {
          posDiff = otherPawn.Location - myPawn.Location;
          normalizedPosDiff = Normal(posDiff);
          normalizedPosDiff *= dotOffsetToHudCenter; //ie. 250 if the distanceto the center is 250px.
          //You could do the stuff with posDiff.Z in here if you want.
          movieclip = RadarMC.AttachMovie("DotMC", "dotInstanceX");
          movieclip.SetPosition(normalizedPosDiff.X, normalizedPosDiff.Y);
      }
      - If your movieclip is as big as the circle it has to move around on, make sure your anchor point is in the center of your movieclip and the dot on the top for movieclip.rotation = 0 degrees (otherwise you'll have to compensate for that in code). In this case, all you'd need to do is rotate the movieclip according to the vector angle.
      Pseudo-code:
      Code:
      //Either clean all movieclip instances or re-use existing and only remove/add movieclips as needed.
      foreach (otherPawn within range)
      {
          posDiff = otherPawn.Location - myPawn.Location;
          rotation = aTan2(posDiff.Y, posDiff.X) * RadToDeg;
          movieclip = RadarMC.AttachMovie("DotMC", "dotInstanceX");
          movieclip.SetFloat('_rotation', rotation);
      }
      NOTE: Keep in mind that since we are rotating in this case that if you did the triangle thing to indicate height difference, the pointing direction of the triangle would become invalid.


      I hope this has been of some help.

      Comment


        #4
        thanks for the help..
        Forgot to tell that, actually in my flash/scaleform, I have set the ring = 361 frames...
        Meaning that the dot will follow exactly the degree on that ring, if the degree is 24 so it will stop at frame 24...
        For the extra frame (361) is for the player is died or missing so the dot will be temporarily "deleted" from the HUD (I use GotoAndStopI(361); )
        As you said, I need a new instance of blue dot in my MC, If I have 10 players, I need 10 blue dots in my MC...
        so, did I need to put any AS in each instance and what is the instance name I should put??
        How actually it will know this instance name is for that particular player??
        Cause I not sure it can be just like : lets say (just a example)
        For (Player = 0; player <= 10; player++)
        {
        Inside here : each time a player joined, player + 1; then in Flash, player 1 = dotA, player 2 = dotB (Can I do that??)
        }
        -----------------------------------------------
        I actually just need to convert X, Y, Z to 360 degree then I can use GoToAndStopI to stop the frame (exact location of target pawn)
        The main problem now is, how the "dots" (the instance name of each dot) know which is belonging to which pawn.

        Thanks....

        Comment


          #5
          Well, the dots don't need to know which player they belong to right? You just loop the pawns and update the next dotMC instance.
          Say you have 10 pawns and 10 dots, it doesn't matter which dot is used for which pawn as long as each single dot is used for a single pawn. This can be Pawn 1 <-> Dot 5 and the next iteration it can be Pawn 1 <-> Dot 3. That doesn't matter at all.

          Assuming your frames are 360 places clockwise, the second code snippet should work for you. Just replace 'movieclip.SetFloat('_rotation', rotation);' with 'movieclip.GotoAndStopI(rotation)'.


          EDIT: Some more pseudo-code:
          Code:
          int lastPawnCount; //This needs to be a global variable to know how much to clean later.
          
          
          //The following takes care of updating existing and creating new movieclips.
          int pawnCounter = 0;
          foreach (otherPawn within range)
          {
              posDiff = otherPawn.Location - myPawn.Location;
              rotation = aTan2(posDiff.Y, posDiff.X) * RadToDeg;
              movieclip = RadarMC.AttachMovie("DotMC", "dotInstance"$pawnCounter);
              movieclip.GotoAndStopI(rotation);
          
              pawnCounter++;
          }
          
          //This takes care of cleaning up the excess movieclips that we no longer need.
          for (int i = pawnCounter; i < lastPawnCount; i++)
          {
              RadarMC.GetObject("dotInstance"$i).GotoAndPlayI(361);
          
              //Or completely remove it. Don't know exactly how but I believe it was something along the lines of either:
              //RadarMC.GetObject("dotInstance"$i).Invoke("removeMovieClip");
              //OR
              //RadarMC.SetObject("dotInstance"$i, null);
          }
          
          //Save the amount of pawns we have on radar now so we can compare again in the next iteration.
          lastPawnCount = pawnCounter;
          EDIT2: You could ofcourse utilize an array in US to store created movieclips so you don't have to call AttachMovie/GetObject for movieclips within the array bounds.
          If you where to do so, you'd need to call AttachMovie only if pawnCounter is greater then the array size. Add the newly created movieclip to the array as well.
          To handle the excess movieclips, you loop from the end of the array to the value of pawnCounter and call '.GotoAndPlayI(361)' on each. (or remove them completely from both the HUD and array)
          Utilizing an array may be a lot faster since you don't have to get the objects through Scaleform over and over again, but this is just an assumption and I haven't actually measured the performance difference.

          Comment


            #6
            sorry for late reply...
            Thanks for the information you gave...
            so far , I have done the degree angle, but not accurate (Cause the result of the angle degree is different from what I want)
            Need find other method to calculate...
            For the dots, still working on it...
            Not really sure how it works...
            Still trying on that...

            Thanks~

            Comment


              #7
              Originally posted by wongkh View Post
              so far , I have done the degree angle, but not accurate (Cause the result of the angle degree is different from what I want)
              Need find other method to calculate...
              What are you getting and what do you want?

              Originally posted by wongkh View Post
              For the dots, still working on it...
              Not really sure how it works...
              Not sure how what works? You set up the dots in Flash yourself so I hope that is not what you ment here...


              Maybe post some of your code so I can give some more specific information. Right now I've nothing to go on.

              Comment


                #8
                okay...
                1.) Degree Angle
                - the calculation from 2 dots is correct, but the degree is not the result I want, cause what I need is the calculation is start from player facing direction...
                - Its like a compass
                - Standing at a same point, but If I facing at different direction, the degree angle should changed...

                Code:
                simulated function FindSatelite(){
                	Foreach AllActors(class'BLUSatelite', FTQuery)
                	{
                		FTS = FTQuery;
                	}
                }
                
                
                function int SatelliteLocation()
                {
                	local vector MyPawn;
                	local float FinalRotation;
                	
                	MyPawn = Normal(Self.Location - FTS.Location);
                	FinalRotation = aTan2(MyPawn.X, MyPawn.Y) * RadToDeg;
                	
                	
                
                
                	Worldinfo.Game.Broadcast(self ,"Satelite location: "@FTS.Location@"");
                	Worldinfo.Game.Broadcast(self ,"My location: "@Self.Location@"");
                	
                	Worldinfo.Game.Broadcast(self ,"Degree angle: "@FinalRotation@"");
                	
                	return FinalRotation;
                }
                2.) Flash/Scaleform
                - I know what you mean, but I never use this looping to call the dots I have created in my flash, so I not sure how to start with it...
                - I have think another method...But I scare this is not a good method to go..
                - My own idea is create 10 dots with unique name n flash, for example dot1, dot2, dot3, dot4 and so on.....
                - Then foreach to get all pawns, each pawns have a specific dots, so the pawn will always use that dot only..
                - If I do so, the code will quite long, cause have to set each player for each dot.
                - Then have to assign every degree angle(Player and target) into the dots.

                This is how it works on my GFx, I give a example using HP Bar, cause the degree angle I also use same method...

                Code:
                class BLUGFx extends GFxMoviePlayer;
                
                var GFxObject HPValue,
                var int LastHealthValueCount,
                var Vehicle DrivenVehicle;
                var float CurrentHealth;
                
                function Init(Optional LocalPlayer LocalPlayer)
                {
                	super.Init(LocalPlayer);
                	
                	Start();
                	Advance(0);
                        HPValue = GetVariableObject("_root.HUD.HPBar");
                }
                
                function TickHUD()
                {
                	if(GetPC().Pawn == none)
                	{
                		return;
                	}
                
                
                	BLUP = GetPC().Pawn;
                	UTGRI = UTGameReplicationInfo(BLUP.Worldinfo.GRI);
                	DrivenVehicle = Vehicle(BLUP);
                	BLUDrivenVehicle = BLUVehicle(BLUP);
                
                	if(DrivenVehicle != none)
                	{
                                BLUDrivenVehicle = BLUVehicle(DrivenVehicle);
                
                                CurrentHealth = (DrivenVehicle.Health * 100) / DrivenVehicle.HealthMax;
                
                                HPValue.GoToAndStopI(CurrentHealth);
                        }
                }
                Btw, want to ask something...
                How can I insert a image from my computer...
                When I pressed "insert image", I only can insert image via URL.
                But my friend one, can choose either using URL or from My Computer...

                Comment


                  #9
                  1) Oh yea right. I forgot to account for the player orientation. Sorry about that. Fixed in the pseudo-code below.
                  2) Well I was hoping my pseudo-code would have helped. If you do the hard-coded thing, you loose the ability to have more or less then 10 dots.
                  And as I said previously, it does not matter which pawn uses which dot as long as each pawn has its own dot. I'll demonstrate with 3 pawns:
                  Originally posted by Tick 1
                  Dot 1 <-> Pawn 2
                  Dot 2 <-> Pawn 3
                  Dot 3 <-> Pawn 1
                  Originally posted by Tick 2
                  Dot 1 <-> Pawn 3
                  Dot 2 <-> Pawn 1
                  Dot 3 <-> Pawn 2
                  Since the loop does not guarantee that the pawns are iterated in the same order each time, the dot used for a pawn may change between ticks. But as you can see each Pawn has its own dot so that does not matter at all.
                  The loop in the pseudo-code is pretty much all you need. I made the pseudo-code a bit more concrete (less 'pseudo' ;P) so I hope that helps.

                  Code:
                  //These variables need to be global.
                  int radarRange; //The range of your radar. Initialize in DefaultProperties or something.
                  int lastPawnCount; //Used to clean excess movieclips
                  GFxObject radarMC; //The movieclip to which to add the dots. Initialize in 'Init(..)' as you're doing with the HPValue.
                  
                  
                  //The following block takes care of updating existing and creating new movieclips and should be run every tick.
                  //------------------------------
                  local Vector playerLookDir;
                  local int pawnCounter;
                  local YourPawn otherPawn; //Replace 'YourPawn' with the class name of your pawn.
                  local int
                  local GFxObject movieclip;
                  local int i;
                  
                  playerLookDir = Vector(PlayerOwner.GetViewRotation());
                  
                  foreach OverlappingActors(class'YourPawn', otherPawn, radarRange, PlayerOwner.Pawn.Location)
                  {
                      if (otherPawn == PlayerOwner.Pawn) //Ignore yourself
                      {
                          continue;
                      }
                  
                      rotation = ACos(playerLookDir dot Normal(otherPawn.Location - myPawn.Location)) * RadToDeg;
                      movieclip = RadarMC.AttachMovie("DotMC", "dotInstance"$pawnCounter);
                      movieclip.GotoAndStopI(rotation);
                  
                      pawnCounter++;
                  }
                  
                  //This takes care of cleaning up the excess movieclips that we no longer need.
                  for (i = pawnCounter; i < lastPawnCount; i++)
                  {
                      radarMC.GetObject("dotInstance"$i).GotoAndPlayI(361); //The 'hidden' index you said you had, or just delete them completely.
                  }
                  
                  //Save the amount of pawns we have on radar now so we can compare again in the next tick.
                  lastPawnCount = pawnCounter;
                  //------------------------------
                  EDIT: Dug up some info about instantiating and removing movieclips through US. Check this topic: https://forums.epicgames.com/threads...m-UnrealScript

                  Comment


                    #10
                    okay..
                    I will try that..
                    Thanks for your help..
                    Really appreciate...

                    Comment

                    Working...
                    X