logo
Main

Forums

Downloads

Unreal-Netiquette

Donate for Oldunreal:
Donate

borderline

Links to our wiki:
Wiki

Walkthrough

Links

Tutorials

Unreal Reference

Usermaps

borderline

Contact us:
Submit News
Page Index Toggle Pages: 1 [2] 3  Send TopicPrint
Very Hot Topic (More than 25 Replies) Collapsing pain zone (Read 544 times)
Feralidragon
Full Member
***
Offline



Posts: 151
Location: Lisbon - Portugal
Joined: Jul 24th, 2008
Gender: Male
Re: Collapsing pain zone
Reply #15 - Feb 14th, 2018 at 1:00am
Print Post  
Yeah, you could use playerstarts and perhaps inventory and path nodes for that, but still for best results you would need to make sure that the point is still center-ish concerning the map itself.

You could also prepare some maps in advance with an actor in them, or better yet, add the ability to set the center point for some of them manually from an ini file (a list of structs, each one with the map filename and associated center point vector, for example).

There are more ways of doing that automatically, which may yield better results overall, but they would need you to put in a lot more work for what may amount to very little gain in return, so probably is best to keep it simple and reliable at least, as you mentioned.


As for the full mesh rendering, yeah, that's the class, and the code is indeed denser and a bit more convoluted than it should be, especially since it has a few more features in it, such as the full view only being activated within a specific range, to not be rendered all the time.

The key part is this one:
Code
Select All
newOffset = (camLoc - CentralLoc) + vector(camRot)*(FMax(FMin(camActor.CollisionRadius, camActor.CollisionHeight) - 1, 1.0));
SetLocation(CentralLoc + newOffset);
PrePivot = -newOffset;
 


In that class, the actor which holds the mesh is responsible for updating itself, so this in the perspective of the mesh actor itself.
As for the vars:
camLoc: the current player camera location;
camRot: the current player camera rotation;
CentralLoc: the location the mesh is actually meant to be at all times, and where you want it to remain.

From there, the newOffset is calculated based on all of this, and in a way that at the end the offset is at least 1uu of distance from the camLoc.
As for the collision itself, I am not entirely sure why I did that anymore, but I think it's a way to account for sudden changes in direction or location from the camera actor (which may be the player itself or someone the player is seeing from, like a guided redeemer warhead), so perhaps a simpler version would look like this:
Code
Select All
newOffset = (camLoc - CentralLoc) + vector(camRot);
SetLocation(CentralLoc + newOffset);
PrePivot = -newOffset;
 



The tricky part is then to ensure the "when" this gets updated, and it must always be one of the very last things, otherwise it won't work very well, since if you're moving forward, or the actor you're seeing from, odds are that if this is updated first, that the mesh starts to lag behind and to never appear.

That's what this part is all about:
Code
Select All
//If has an updater
if (localUpdater != None && Delta != 0.5)
{
	updateDelta = Delta;
	return;
}
else if (Delta == 0.5)
	Delta = updateDelta;

//Check ViewTarget for "no-lag" updates
if (localPlayer.ViewTarget != None && localUpdater == None)
{
	if (localViewTarget == None)
	localViewTarget = localPlayer.ViewTarget;
	localUpdater = Spawn(Class'NWCorUpdaterFX');
	localUpdater.CorToUpdate = Self;
}
else if (localPlayer.ViewTarget != None && localViewTarget != localPlayer.ViewTarget && localUpdater != None)
{
	localViewTarget = localPlayer.ViewTarget;
	localUpdater.Destroy();
	localUpdater = Spawn(Class'NWCorUpdaterFX');
	localUpdater.CorToUpdate = Self;
}
else if (localPlayer.ViewTarget == None && localUpdater != None)
{
	localViewTarget = None;
	localUpdater.Destroy();
	localUpdater = None;
}
 


This is something used not only in this class, but some others, but essentially what I did back then is to ensure that I had an actor that was always ticked after the actor I was looking after.

This has worked pretty much flawlessly thus far in practice, although in theory any actor which manages to change the location abruptly of this ViewTarget after this actor gets ticked may still mess things up, hence perhaps the little margin using the collision, and the code overall is a bit messy and hack-ish, something I am not really proud of at all.


In other words, a potential better way of doing this would be to have a central actor/manager which could tick these kinds of actors at the very end of each tick, after every single actor has been ticked already and there's no chance of abrupt changes, which I have a feeling it may be possible to do so without a brute-force like this one, but I didn't look into it yet, so I am not sure how atm.
  
Back to top
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 762
Joined: Jul 31st, 2008
Gender: Male
Re: Collapsing pain zone
Reply #16 - Feb 14th, 2018 at 2:13pm
Print Post  
Ah ok, got it! Now the class makes sense. I'm doing some custom actor stuff for Krullor but I'll get a prototype for the collapsing zone done this weekend. It's a holiday for us on Monday so I'll have a clear couple of days.

Conceptually do you think it's best to pick a point in this order?
If there are pathnodes, pick one of those first.
If not pick a weapon pickup.
If map is empty pick a playerstart.

Of course I'll add a proximity check to see if the area is clear. I'm aware that some games will end in not-so-desirable spots but that's also a charm in itself. At least no game will ever be such that it won't end because the zone will ensure it finishes one way or the other.
  

I'm outta here. C ya!
Back to top
 
IP Logged
 
Feralidragon
Full Member
***
Offline



Posts: 151
Location: Lisbon - Portugal
Joined: Jul 24th, 2008
Gender: Male
Re: Collapsing pain zone
Reply #17 - Feb 14th, 2018 at 8:49pm
Print Post  
I think you should use them all, without a specific order, and come up with a location closest to the center of the map (which could either correspond to one of those nodes).

In order to do this, you could iterate through them all, and sum their vectors in a single one and count the number of them, which then you could use to find the average location, and then find the node closest to it.

Keep in mind though that using a playerstart should really be the very last resort, to be entirely avoided if possible even if that means do some tracing around or use something else like a light actor (similarly to what Higor did in Siege), given that the proximity by which a player spawns relative to the center of the pain zone will greatly influence the chances that each player will have in surviving in the end, or at least the longest.

Ideally, players should spawn at about the same distance from the center, but as far away from it as possible and in different locations.
This is something that can be also achieved in a way, but at least the easiest algorithm for this could become very slow depending on the number of overall points to check: the complexity would be O(n x m), where "n" is the number of playerstarts and "m" the number of everything else, which means that with 32 playerstarts and maybe around 500 nodes, this would translate to 16000 iterations, although it would only be needed to be made once.
  
Back to top
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 762
Joined: Jul 31st, 2008
Gender: Male
Re: Collapsing pain zone
Reply #18 - Feb 15th, 2018 at 1:58am
Print Post  
I understand your philosophy but I'll tell you that having played multiple hundreds of hours of PUBG you couldn't be more wrong Wink

I'm only joking but once you understand the dynamics of the game it can become redundant. Having circles that end at a cliff edge or even out in the water become some of the most memorable matches I've ever played. It's also a very valid playstyle to hide as long as possible. I've won a couple of chicken dinners doing this myself.

Anyway it's been my experience that the more absolute randomness of the circle placement the more that players enjoy it. For a while the circle kept falling on military base in PUBG and the players were very unhappy. Now the circle falls all over the map. I think grabbing a random nav point will do just fine. Sure, there will be times when it sucks but it's worth it that you just won't know ahead of time.

Also, I hadn't really talked this part yet but I'll end up replacing all the pickups. This will serve to force the players to have to move around to get gear enough to be offensively effective. I think I'll also look at using the tac ops military weaponry because I think it uses a reload function.

I'm curious too about something. I think I can get bots to work ok with this provided I can teach them to avoid the pain zone. What are your thoughts on that? Is it possible to have them avoid it without having to script new bot classes?
  

I'm outta here. C ya!
Back to top
 
IP Logged
 
Feralidragon
Full Member
***
Offline



Posts: 151
Location: Lisbon - Portugal
Joined: Jul 24th, 2008
Gender: Male
Re: Collapsing pain zone
Reply #19 - Feb 15th, 2018 at 11:02am
Print Post  
I see... but could be that to be so simply because the map is static?

I never played PUBG myself, although I understand the gameplay somewhat, but I tried FortniteBR a while ago which seems to be similar, although in Fortnite you actually choose the area of the map you want to spawn in by jumping from a flying bus lol (not sure if they changed that in the meanwhile, it's been a while).

I understand that within the exact same map, if the zone center is always at the same place, it will make the gameplay go stale very quickly, with players employing the same strategies making it utterly boring rather quickly, so I guess that's a way for it to be more dynamic by changing the zone rather than the map.

Yeah, in that sense, it may work in UT the same way, with a random center.


As for the bots, I am almost certain that's possible.
I am not entirely sure the "how" part right now, but I think it would be along the lines of monitoring where the bots are and if they are relatively close to the edge, to tell them to just turn around, maybe even "deactivating" any nodes already in the pain zone itself.

Also, inventory in the pain zone itself would need to be "burned" to also ensure that bots do not give into temptation into trying to pick loot from the pain zone.
  
Back to top
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 762
Joined: Jul 31st, 2008
Gender: Male
Re: Collapsing pain zone
Reply #20 - Feb 15th, 2018 at 3:16pm
Print Post  
I was thinking about that last night. As the zone progresses I think I'll have the pickups convert to some type of bot avoid spot. I might even have to address pathnodes the same way. This will likely end up with them stuck in spots but overall should keep them moving towards the center as far as that is possible.

As for the collapsing zone I'm still unsure what would be best. I've been really trying to figure out how to bring YRex's suggestion in but I don't see a feasible way. I could mimic that with an octagonal collapse of eight walls but the overlap would be ugly. Really I think your idea of a spherical zone may be the end result if this is done in UT.

Man, I wish more people played Unreal. I could do so much with what U227 has to offer. It's frustrating to have the answer right in front of you but know that it's just not what you can use.
  

I'm outta here. C ya!
Back to top
 
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 762
Joined: Jul 31st, 2008
Gender: Male
Re: Collapsing pain zone
Reply #21 - Feb 17th, 2018 at 1:35pm
Print Post  
Sorry to double post but FeraliDragon has been holding my hand on this ideal of forcing a model to be visible regardless of the origin. He sent me revised and simplified code and I thought it would be helpful to share that here in case anyone else stumbles into this problem.

The revised code:
Code
Select All
var vector OriginalLocation;
var PlayerPawn LocalPlayer;

const ORIGIN_DISTANCE_FROM_PLAYER = 128.0;

simulated function PostBeginPlay()
{
local PlayerPawn PP;

     //run only in client
     if (Level.NetMode != NM_DedicatedServer) {
 	    //save original location
 	    OriginalLocation = Location;

 	    //get local player
 	    foreach AllActors(class'PlayerPawn', PP) {
 		    if (Viewport(PP.Player) != None) {
 			    LocalPlayer = PP;
 			    break;
 		    }
 	    }
     }

     //super
     Super.PostBeginPlay();
}

simulated function Tick(float Delta)
{
     local vector camLoc;
     local rotator camRot;
     local Actor camActor;

     //run only in client
     if (Level.NetMode != NM_DedicatedServer && LocalPlayer != None) {
 	    //get player camera coordinates
 	    LocalPlayer.PlayerCalcView(camActor, camLoc, camRot);

 	    //set location and pre-pivot
 	    PrePivot = (OriginalLocation - camLoc) - vector(camRot) * ORIGIN_DISTANCE_FROM_PLAYER;
 	    SetLocation(OriginalLocation - PrePivot);
     }
}
  



Thank you Ferali for this. I've run into this problem several times and never understood there was a decent solution.

Here's a demo on what I'll be trying to use this code on. I still don't know if this is going to scale up to the size I would like but I'm interested to see how far I can push it:


You can see that the mesh disappears on me even in this simple offline test map. YRex's implementation looks better but I can't see how to use a cylinder given the rudimentary drawscale adjustments I'm forced to use in UT. I went with a sphere because of this Sad
« Last Edit: Feb 17th, 2018 at 3:03pm by gopostal »  

I'm outta here. C ya!
Back to top
 
IP Logged
 
Feralidragon
Full Member
***
Offline



Posts: 151
Location: Lisbon - Portugal
Joined: Jul 24th, 2008
Gender: Male
Re: Collapsing pain zone
Reply #22 - Feb 17th, 2018 at 3:35pm
Print Post  
The "ORIGIN_DISTANCE_FROM_PLAYER" constant may have higher values, so if the mesh still disappears upon movement (the tick problem I mentioned earlier), this value can just be made higher, to something like 512 or even more.

The only thing to look out for is the LOD then.
If the mesh has LOD levels set and a LODBias set to the default value of 1.0, it may morph the polys out, given that the actor would be more distant (512uu instead of 128uu), therefore at a larger scale the LOD level of the mesh should be disabled at import (#exec MESH LODPARAMS MESH=<TheMesh> STRENGTH=0) or the LODBias should be set to 8.0 or higher.



As for the cylinder, you can import a cylinder mesh, and in the import parameters set the Z axis scale to something huge, although I am unsure at which point will just mess it up.

Another way is to have a cylinder mesh in which this shrinkage is handled through animation, by having just a 2-key frame animation, with the first frame with the cylinder open, and the second with all of them collapsed in a single point.

I have used a similar technique to a lot of stuff, mainly things like particle effects (the growing clouds in nukes and oversurrections for example), precise trace effects (sniper trace), stretched cylinders (the guts in the gore mod for example)  and more, but it's relatively hard to set up: you either use MS3D or Blender and write a script in Python to create this animation for you for each vertex, or you use 3DStudio to set up each frame, one with the mesh open, and another with the mesh closed and export it as a single animated mesh.

Either way, it can be done, only the amount of work involved will differ depending on the approach.

  
Back to top
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 762
Joined: Jul 31st, 2008
Gender: Male
Re: Collapsing pain zone
Reply #23 - Feb 18th, 2018 at 4:42pm
Print Post  
Well, I'm actually very surprised at the results of testing. I took the default shockwave mesh, exported with UModel and imported back, stretching it out to 8X on the Z-axis so it resembled much more of a cylinder but still would collapse down to close off any space. I then made a fully open map that stretched almost an entire plane of the editor playfield so I could see it render at max values.

I spawned the collapsing zone at drawscale 1000 (yikes) and started the round. To my great surprise it renders beautifully, collapsing just like it should. Jeez, this might just actually work.

So now question time...
1) Scaling the zone up so high makes it quite ugly for any type of wet/animated texture. Could someone suggest a way to deal with this? I would like to use anything besides a flat color but I will if I have to.
2) I'd like to start the zone out at the edge of the map instead of the edge of the map area. Is there a way to find the furthest edge from the randomly chosen zone center point? I thought about iterating the pickups to find the one with the largest difference in location and using that to compute a size but is there an easier way you know of?
3) Bonus question...is there a way to determine which actors are within the collapsing zone and which are not so I can apply damage? I can do traces to see distance and get pretty close but I wonder if there is a better way?
  

I'm outta here. C ya!
Back to top
 
IP Logged
 
Feralidragon
Full Member
***
Offline



Posts: 151
Location: Lisbon - Portugal
Joined: Jul 24th, 2008
Gender: Male
Re: Collapsing pain zone
Reply #24 - Feb 18th, 2018 at 6:07pm
Print Post  
1 - There are a few ways you can go about this:

1.a) Use a much higher poly mesh, something that has several lines of polys along the Z axis, squeezed in so when you scale it in that axis, they become all rather even.
Not sure how to properly explain this, but something along this:

The UV mapping in this case has to be done in such a way that every line maps to the full texture, so the texture actually appears to be seamless and repeat across them all without being stretched.

1.b) Same premise as above, but instead of a single mesh with several lines, you can use multiple instances of the same mesh, all placed on top of each other.
Although during import, if you don't take the lack of accuracy from the engine and if they are not perfectly aligned at all times, you will see the edges and it won't look great.
But this way the mesh itself is a bit easier to prepare and you could only show the lines you actually need to render instead.


2 - You can only iterate through every actor you can know a location from and then see the max distance, since there's current no way to get the vertex locations from BSP in UScript (at least in UT, not entirely sure in Unreal though).
You can also do some additional tracing in every axis from each one of those locations to try to get the utmost BSP points.


3 - You can simply use a "foreach AllActors" and check their distance from their current location to the center of the zone, and do your magic from there. Smiley
You don't need to do any tracing because the pain zone is supposed to absolute.
There's also RadiusActors, but in this case you want to know what's outside, so it wouldn't help here.
  
Back to top
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 762
Joined: Jul 31st, 2008
Gender: Male
Re: Collapsing pain zone
Reply #25 - Feb 18th, 2018 at 11:40pm
Print Post  
1) I've been experimenting with different animated textures to try to find something that works without making some very heavy poly-ed model. I'll let you know what I end up getting with results from that. Honestly Blender intimidates the crap out of me and doing correct edits on an existing model is above what I can currently do (though I will learn it if this requires model work). I hadn't considered multiple instances of the mesh and this might be a good fit. I can use layers at high drawscale and reduce them as the need lessens and the mesh is at a lower draw.

2) I took a look at a set of random DM maps and I think running through the pickups/spawnpoints will give me a really good start point for the zone size. I figure whatever it returns I can fudge upwards 10% and that will be in the ballpark. Can I trouble you later as I start to try to work through the math? That's where I'm pretty weak. Once it gets to middle-level algebra I'm lost quick. Wish I could have went to college.
EDIT: OK, It boils down to choosing either running a Pythagorean calculation using the coords or doing a trace from location to location. What do you think is faster and/or better?

3) Will a foreach return distance even if that crosses empty space/multiple hits on BSP?

Thanks for hanging in here with me. I'd like to get the gameplay fairly set before I work on weapons and pickups.

« Last Edit: Feb 19th, 2018 at 1:04am by gopostal »  

I'm outta here. C ya!
Back to top
 
IP Logged
 
Feralidragon
Full Member
***
Offline



Posts: 151
Location: Lisbon - Portugal
Joined: Jul 24th, 2008
Gender: Male
Re: Collapsing pain zone
Reply #26 - Feb 19th, 2018 at 1:17am
Print Post  
2 - Yeah, no problem.

3 - A "foreach" generally only iterates through actors, and from there it may only do something more depending on the used iterator.
For instance, only VisibleActors and VisibleCollidingActors take visibility into account (hence the names), while TraceActors does tracing, and so on.

An AllActors iterator does really only do just that, iterate through all the existent actors within the map, as long they belong to the class or a subclass that you specify, so there's no tracing involved whatsoever.

Therefore, from there, to know the distance you only need to do a "VSize(A.Location - CenterLocation)", where A.Location is the iterated actor location and the CenterLocation is the actual center location of the pain zone.

Code
Select All
local Actor A;

foreach AllActors(class'Actor', A) {
	//check if is within the pain zone
	if (VSize(A.Location - CenterLocation) >= CurrentPainZoneRadius) {

		//do damage, inflict pain, destroy stuff, etc...

	}
}
 



From here, you may want to only affect classes like Inventory and Pawn, at which point, depending on how many classes of actors you want to affect, you may want to write a separate foreach for each, or filtering them within a single one (the rule of thumb is: if you have very few main classes to deal with, use multiple foreach statements, it will be more efficient even although in terms of time complexity it shouldn't be, but it cannot be helped given that UScript is 20x slower than C++ iirc).
  
Back to top
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 762
Joined: Jul 31st, 2008
Gender: Male
Re: Collapsing pain zone
Reply #27 - Feb 19th, 2018 at 2:40am
Print Post  
Ugh, I wish I had a cookie for every time I try to say something and it comes out not what I meant. It makes me look so retarded.

I understand about the actor iteration. I didn't fully explain myself, I was trying to do too much at once. I should have said it as "Will a foreach give me actors I can return distance trace even if that crosses empty space/multiple hits on BSP?" Luckily for me you also can read minds.

*Edited my post after testing tonight*...

Thanks for your help. Using your trace example I was able to script checks for the farthest playerstart from the zone's spawn point. I'm converting those distances to drawscale now and I think it should all be good. There's still a lot to work out like how fast to collapse and such but it's nice to know the core is good thanks to you.
« Last Edit: Feb 19th, 2018 at 5:34am by gopostal »  

I'm outta here. C ya!
Back to top
 
IP Logged
 
Feralidragon
Full Member
***
Offline



Posts: 151
Location: Lisbon - Portugal
Joined: Jul 24th, 2008
Gender: Male
Re: Collapsing pain zone
Reply #28 - Feb 19th, 2018 at 11:57am
Print Post  
I will be honest: I also found it weird that you would make that kind of question concerning a "foreach", but I opted to just reply to it rather than questioning it.


On your 2) edit: on the off-chance I am misunderstanding you, what exactly do you mean by "trace from location to location"?
I am asking this because a Pythagorean calculation as you said (which is what VSize does) is the only viable way to know the distance from location A to location B, therefore coordinates are the only things you need to know how big something is, you don't need to know or trace anything in BSP itself or anything else.

The only tracing you could do would be to check the surroundings around each location, so you could get a better insight on how big the map actually is, but you already said that you would just add 10% to the distance, which sounds very reasonable and a good way of doing things, so I guess this is not what you meant.


PS: This discussion made me install and check out FortniteBR again.
Been having a blast with it ever since.  Grin
(although I didn't win a single match yet, but at least managed to be at 6th place thus far, out of 100)

But the pain zone mechanics there seem to differ a bit from what you described from PUBG: it's spawned at random locations, but not just 1 single location.
Instead, it starts out with no pain zone at all, then the center is somewhere random in the map, but not too random since the initial radius is big and has to be contained within the map, then each 2-3 minutes it shrinks a bit, stops, then a new point within the current radius is chosen, and only starts shrinking again after a few minutes.

By the end of the game it gets faster, changes more frequently, and the damage it gives is much higher.
  
Back to top
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 762
Joined: Jul 31st, 2008
Gender: Male
Re: Collapsing pain zone
Reply #29 - Feb 19th, 2018 at 3:11pm
Print Post  
Yeah, it's a little frantic. TBH I prefer PUBG over Fortnite simply because I'm not good enough to use the building mechanics well as part of the game strategy. For me (and for this old of an engine) the simpler play is just better because there is less to track all the time.

I had never done a trace across empty space between open BSP and I did not know if it would return proper values. I didn't know that's what VSize actually did. Turns out it works like a charm. I figured out the ratio last night and it's a bit surprising:

If you take a mesh about the size a player could fit inside of, this compared to the player's default size, then to reach just past a marker 2048uu away you need to inflate the mesh drawscale 73.25 times. This is linear too and works all the way up to 805.75X, which is roughly going from the center of the usable field out to near the edge of the usable field (diameter). In testing it seems the engine does not care if the mesh renders out of bounds so long as the origin remains in the map play area. This is a visual of my testing map if that helps you see. The pic is very large, that's why I'm not embedding it: https://imgur.com/vVeA4Km

Today I'll work out the pain zone part of this and test in some various DM maps. If it's all good then I'll probably work on the weapons and replacement mutator parts of the mod. I've been using the CS 1.6 weapons and it seems a good fit. Forced reload will slow things down some and allow the hit player a chance to run and bandage up.

I'm glad you played a bit of Fortnite. Hopefully you see the draw of this game mechanic and hopefully it could bring some interest into regular DM play.

Edit: Got finished with the implementation of the zone, here's a demo video. The mutator is finding a random playerstart and the distance to the farthest other start. It then computes the correct drawscale and spawns the zone. I sped this zone collapse way up so it won't waste any of your time. There will be steps along the way where the zone will pause and it will stop in an area small enough for two people to face off in before finally collapsing totally. I want to give the final two an option to knife fight for the win if they want Smiley


I tried your code to force the mesh to exist but it didn't seem to help. If you aren't facing the origin the mesh will blink out Sad  Man, it's frustrating to be this close and still not there...hahaha
« Last Edit: Feb 19th, 2018 at 11:43pm by gopostal »  

I'm outta here. C ya!
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1 [2] 3 
Send TopicPrint
Bookmarks: del.icio.us Digg Facebook Google Google+ Linked in reddit StumbleUpon Twitter Yahoo