How to find a location near player but out-of-sight to avoid

Post » Fri Jun 22, 2012 1:11 am

Both http://www.creationkit.com/MoveTo_-_ObjectReference & http://www.creationkit.com/SetPosition_-_ObjectReference have the following note:

"... should be avoided for placing other actors in sight of the player, as they will suddenly appear in an unrealistic way. Instead, consider placing them nearby but out of sight, and making them approach the player themselves, using http://www.creationkit.com/PathToReference_-_Actor or http://www.creationkit.com/ForceGreet_(Procedure)."

The PathToReference part is easy. But, what is a good way to determine a location that is nearby but out-of-site? I know there is http://www.creationkit.com/IsNearPlayer_-_ObjectReference for checking an object... but is there a clean way to find coordinates?
User avatar
saharen beauty
 
Posts: 3456
Joined: Wed Nov 22, 2006 12:54 am

Post » Thu Jun 21, 2012 2:53 pm

Okay, so most likely I'm not missing somethings obvious. (I was hoping I was!)

I can think of alternative approaches, like randomly finding objects x disatance away and checking if they are out-of-sight, which seems fine in normal situations... but not sure of side affects, like placing the actor above the player on a cliff or something. Or I could just move the (new) actor to a set distance, like 3000 units away from the player, but again, how do I know if i put them in the middle of the water or over the side of a mountain or something?
User avatar
RObert loVes MOmmy
 
Posts: 3432
Joined: Fri Dec 08, 2006 10:12 am

Post » Thu Jun 21, 2012 10:44 pm

If you can find an excuse to force the player's camera into first person (or maybe just to make the camera in 3rd Person forced a certain way? Not sure if you can control 3rd Person Camera Angle through papyrus), then you could just have the actor appear behind the player.
User avatar
Stay-C
 
Posts: 3514
Joined: Sun Jul 16, 2006 2:04 am

Post » Thu Jun 21, 2012 1:31 pm

Thanks AstrolFire... that's how i did it... works fine. I put him about 400 units behind the player so even in third person, he's may not be visible. It's not perfect, but it works great. Thanks for the feedback!

BTW, Other than SetCameraTarget, I don't know of a way to control the camera angle through Papyrus in either 1st or 3rd person, do you? I know you can set 1st or 3rd person view using ForceFirstPerson and ForceThirdPerson, respectively.
User avatar
Justin
 
Posts: 3409
Joined: Sun Sep 23, 2007 12:32 am

Post » Thu Jun 21, 2012 1:58 pm

If you know where your player is going to be you could always hand-pick a location that isn't going to be visible. For instance, attach the quest pointer to a marker on one side of a building, and then have the newcome materialse on the other side where he won't be seen.

For general wilderness encounters you could start them from the nearest town or farmhouse over a certain distance away and use path to reference. It all depends on how fast they need to arrive, once triggered.
User avatar
Nicola
 
Posts: 3365
Joined: Wed Jul 19, 2006 7:57 am

Post » Thu Jun 21, 2012 2:43 pm

If you know where your player is going to be you could always hand-pick a location that isn't going to be visible. For instance, attach the quest pointer to a marker on one side of a building, and then have the newcome materialse on the other side where he won't be seen.

For general wilderness encounters you could start them from the nearest town or farmhouse over a certain distance away and use path to reference. It all depends on how fast they need to arrive, once triggered.

Thanks DocClox - that's a great suggestion if it were a pallned encounter, but the player could be anywhere... interior or exterior.
User avatar
Wayne Cole
 
Posts: 3369
Joined: Sat May 26, 2007 5:22 am

Post » Thu Jun 21, 2012 3:50 pm

Thanks DocClox - that's a great suggestion if it were a pallned encounter, but the player could be anywhere... interior or exterior.

You're bringing the Mysterious Stranger to Skyrim? :cool:
User avatar
benjamin corsini
 
Posts: 3411
Joined: Tue Jul 31, 2007 11:32 pm

Post » Thu Jun 21, 2012 1:35 pm

If you can have the NPC spawn at a particular place and just need to wait until the player isn't looking at the spawnpoint, you could place an invisible Activator that checks once a second or so for Player distance and LOS. When the player gets within the desired distance and doesn't have LOS, the Activator places the NPC and deletes itself.

If the NPC needs to spawn wherever the player is, but out of sight, maybe you could try making the actor invisible with SetAlpha and follow the player around until they don't have LOS, then make them visible... of course then you run the risk of enemies attacking them, but you can probably fix that with some creative use of Factions. Or, use a completely invisible actor with an empty model (I think dunMIddenRace fits the bill) to follow the player around and place the NPC when player has no LOS.


Edit: It's the G-Man. You're making the G-Man, aren't you?
User avatar
Jessie Rae Brouillette
 
Posts: 3469
Joined: Mon Dec 11, 2006 9:50 am

Post » Thu Jun 21, 2012 5:02 pm

You're bringing the Mysterious Stranger to Skyrim? :cool:

Lol, no, I'm doing this to call my animal companion, so the player could be anywhere when they call him.


If you can have the NPC spawn at a particular place and just need to wait until the player isn't looking at the spawnpoint, you could place an invisible Activator that checks once a second or so for Player distance and LOS. When the player gets within the desired distance and doesn't have LOS, the Activator places the NPC and deletes itself.

If the NPC needs to spawn wherever the player is, but out of sight, maybe you could try making the actor invisible with SetAlpha and follow the player around until they don't have LOS, then make them visible... of course then you run the risk of enemies attacking them, but you can probably fix that with some creative use of Factions. Or, use a completely invisible actor with an empty model (I think dunMIddenRace fits the bill) to follow the player around and place the NPC when player has no LOS.

Edit: It's the G-Man. You're making the G-Man, aren't you?
That's a very interesting approach Verteiron! And certainly not one I would have thought to use. I think this is an idea waiting for a mod! :wink:

Maybe I need to make a stalker mod...
User avatar
Stryke Force
 
Posts: 3393
Joined: Fri Oct 05, 2007 6:20 am

Post » Fri Jun 22, 2012 2:19 am

I basically calculate the sides of the right-angle triangle defined by the target viewing angle radius as the hypotenuse, and the angle created between that target viewing angle and adjacent X/Y axis.


Scriptname phiPlaceBehindScript extends ActiveMagicEffectObjectReference Property phiPlayer auto	 ; I usually pick the player ref in the CK after compiling.ObjectReference Property myRef auto 		; The actor/object you are placing. Also defined in CK.Event OnEffectStart(Actor akTarget, Actor akCaster)float xpos = phiPlayer.GetPositionX()		 ; The next three lines get the X and Yfloat ypos = phiPlayer.GetPositionY()		 ; position of the player and their current viewing angle.float zAngle = phiPlayer.GetAngleZ()float xdistance = 216			; This is the number of game units from the player you want to place the object.if zAngle < 180				 ; This if loop is to offset our target viewing angle 180 degrees	zAngle = zAngle + 180		; which will be directly behind us, and also checks for a valueelse						  ; between 0-360 which may not be necessary.	zAngle = zAngle - 180endif; This section does the actual calculations. Given the circle defined with the player as the center point and a radius equal tothe xdistance value, I subtract 90 degrees from the target angle for each full quadrant between that direction and0 degrees, so I can then calculate the unknown sides of the right-angle triangle defined between that target angle andthe nearest adjacent X/Y axis. The xdistance value (216 in this example) becomes the hypotenuse of this triangle.		if zAngle == 0	; These first four loops are easy, for when the target viewing angle falls exactly on an axis.		xdes = xpos		ydes = ypos + xdistance		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	elseif zAngle == 90		xdes = xpos + xdistance		ydes = ypos		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	elseif zAngle == 180		xdes = xpos		ydes = ypos - xdistance		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	elseif zAngle == 270		xdes = xpos - xdistance		ydes = ypos		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)			elseif zAngle <= 89.999		float xoffset = xdistance * Math.sin(zAngle)	; This side of the triangle becomes our x-offset,		float yoffset = xdistance * Math.cos(zAngle)	; and this the y-offset. We add these to the player's		xdes = xpos + xoffset					; X and Y position to place our reference.		ydes = ypos + yoffset		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	; Does the final positioning.	elseif zAngle <= 179.999 				   ; You may need to MoveTo/PlaceAtMe disabled before doing this.		float xoffset = xdistance * Math.cos(zAngle - 90)	; Different calculations for the other quadrants the		float yoffset = xdistance * Math.sin(zAngle - 90)	; target angle may fall in, same idea.		xdes = xpos + xoffset		ydes = ypos - yoffset		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	; I add 45 so the ref appears slightly above ground.	elseif zAngle <= 269.999		float xoffset = xdistance * Math.sin(zAngle - 180)		float yoffset = xdistance * Math.cos(zAngle - 180)		xdes = xpos - xoffset		ydes = ypos - yoffset		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	elseif zAngle <= 359.999		float xoffset = xdistance * Math.cos(zAngle - 270)		float yoffset = xdistance * Math.sin(zAngle - 270)		xdes = xpos - xoffset		ydes = ypos + yoffset		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	endifEndEvent

Here is the same code, without my comments:

Spoiler
Scriptname phiPlaceBehindScript extends ActiveMagicEffectObjectReference Property phiPlayer autoObjectReference Property myRef autoEvent OnEffectStart(Actor akTarget, Actor akCaster)	float xpos = phiPlayer.GetPositionX()	float ypos = phiPlayer.GetPositionY()	float zAngle = phiPlayer.GetAngleZ()	float xdistance = 216	if zAngle < 180		zAngle = zAngle + 180	else		zAngle = zAngle - 180	endif	if zAngle == 0		xdes = xpos		ydes = ypos + xdistance		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	elseif zAngle == 90		xdes = xpos + xdistance		ydes = ypos		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	elseif zAngle == 180		xdes = xpos		ydes = ypos - xdistance		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	elseif zAngle == 270		xdes = xpos - xdistance		ydes = ypos		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	elseif zAngle <= 89.999		float xoffset = xdistance * Math.sin(zAngle)		float yoffset = xdistance * Math.cos(zAngle)		xdes = xpos + xoffset		ydes = ypos + yoffset		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	elseif zAngle <= 179.999		float xoffset = xdistance * Math.cos(zAngle - 90)		float yoffset = xdistance * Math.sin(zAngle - 90)		xdes = xpos + xoffset		ydes = ypos - yoffset		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	elseif zAngle <= 269.999		float xoffset = xdistance * Math.sin(zAngle - 180)		float yoffset = xdistance * Math.cos(zAngle - 180)		xdes = xpos - xoffset		ydes = ypos - yoffset		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	elseif zAngle <= 359.999		float xoffset = xdistance * Math.cos(zAngle - 270)		float yoffset = xdistance * Math.sin(zAngle - 270)		xdes = xpos - xoffset		ydes = ypos + yoffset		myRef.SetPosition(xdes, ydes, phiPlayer.GetPositionZ() + 45)	endifEndEvent
User avatar
Austin Suggs
 
Posts: 3358
Joined: Sun Oct 07, 2007 5:35 pm

Post » Thu Jun 21, 2012 12:26 pm

Thanks Phinix!

Very nice and I'll keep your code in mind. I'll be honest, I am using a much simpler code to put my animal behind the player:
Float xPos = (200 * Math.Sin(game.GetPlayer().GetAngleZ()+180))Float yPos = (200 * Math.Cos(game.GetPlayer().GetAngleZ()+180))dog.MoveTo(Game.GetPlayer(), xPos, yPos, 0,True)

I put the dog close to the player to lessen the chance of a bad placement, like a rock or water behind the player, but I know it's not "fool proof". I'm also relying on the npc MoveTo to place the animal at the ground level. I read on the forums that PlaceAtMe does that (and my testing confirmed it) and so far, MoveTo seems to also. I looked to see if your code specifically handled placement issus, but I don't see anything to indicate that it does.
User avatar
Katie Louise Ingram
 
Posts: 3437
Joined: Sat Nov 18, 2006 2:10 am

Post » Thu Jun 21, 2012 6:53 pm

Thanks Phinix!

Very nice and I'll keep your code in mind. I'll be honest, I am using a much simpler code to put my animal behind the player:
Float xPos = (200 * Math.Sin(game.GetPlayer().GetAngleZ()+180))Float yPos = (200 * Math.Cos(game.GetPlayer().GetAngleZ()+180))dog.MoveTo(Game.GetPlayer(), xPos, yPos, 0,True)

I put the dog close to the player to lessen the chance of a bad placement, like a rock or water behind the player, but I know it's not "fool proof". I'm also relying on the npc MoveTo to place the animal at the ground level. I read on the forums that PlaceAtMe does that (and my testing confirmed it) and so far, MoveTo seems to also. I looked to see if your code specifically handled placement issus, but I don't see anything to indicate that it does.

That's mostly why I add 45 to the Z position relative to the player, so that if there is an obstacle the game has more room to fit the reference in.

I like your streamlined script. Mine could probably be simplified quite a bit.

I'm not sure why I was so concerned with right angle triangles when I wrote it.

The most familiar trigonometric functions are the http://en.wikipedia.org/wiki/Sine, cosine, and tangent. In the context of the standard unit circle with radius 1, where a triangle is formed by a ray originating at the origin and making some angle with the x-axis, the sine of the angle gives the length of the y-component (rise) of the triangle, the cosine gives the length of the x-component (run), and the tangent function gives the slope (y-component divided by the x-component).

http://en.wikipedia.org/wiki/Trigonometric_functions

Yeah, I feel stupid now. =P

But I'm confused. If you already have the equation to place your reference behind the player, isn't this sufficient to have them spawn "out of sight?"
User avatar
Misty lt
 
Posts: 3400
Joined: Mon Dec 25, 2006 10:06 am

Post » Thu Jun 21, 2012 8:56 pm

You can use a spell with Target Location delivery and Snap To Navmesh to guarantee the NPC spawns at a workable location, but that's pretty roundabout. It's how Summon spells work, though.
User avatar
Stace
 
Posts: 3455
Joined: Sun Jun 18, 2006 2:52 pm

Post » Thu Jun 21, 2012 6:23 pm

I remember a thread by redwood elf for a tutorial for making your own custom courier, and in it he had an interesting method for accomplishing what you need. Do a search in this forum for "[tools] you get a letter from WHAT" (I think that's what he named it). I would have provided a link myself but my Internet is going really slow on my phone for some reason

- Hypno
User avatar
Jason Rice
 
Posts: 3445
Joined: Thu Aug 16, 2007 3:42 pm

Post » Thu Jun 21, 2012 8:34 pm

I just remembered something. blakeyrat wrote a mod that makes a statue follow you around when you're not looking at it AND he uploaded the script for it to Google. It's here: https://code.google.com/p/blakeyrats-skyrim-mods/source/browse/trunk/Data/Scripts/Source/para_ParanoiaScript.psc

Looks like he's using an invisible follower. His function for checking LOS looks overly complicated to me, but he may be doing something there I'm not seeing or working around a bug. Either way, probably a helpful reference for you!
User avatar
Adam
 
Posts: 3446
Joined: Sat Jun 02, 2007 2:56 pm

Post » Thu Jun 21, 2012 2:45 pm

I remember a thread by redwood elf for a tutorial for making your own custom courier, and in it he had an interesting method for accomplishing what you need. Do a search in this forum for "[tools] you get a letter from WHAT" (I think that's what he named it). I would have provided a link myself but my Internet is going really slow on my phone for some reason

- Hypno

Thanks Hypno, I found the thread http://www.gamesas.com/index.php?act=findpost&pid=20516199 (it was pretty easy with your title, so thanks! Funny thing, I remember seeing the thread, but didn't read it much since I wasn't in need of a courier ;) I'm looking at his BeamIn thread function now.
User avatar
Ray
 
Posts: 3472
Joined: Tue Aug 07, 2007 10:17 am

Post » Fri Jun 22, 2012 3:38 am

I just remembered something. blakeyrat wrote a mod that makes a statue follow you around when you're not looking at it AND he uploaded the script for it to Google. It's here: https://code.google.com/p/blakeyrats-skyrim-mods/source/browse/trunk/Data/Scripts/Source/para_ParanoiaScript.psc

Looks like he's using an invisible follower. His function for checking LOS looks overly complicated to me, but he may be doing something there I'm not seeing or working around a bug. Either way, probably a helpful reference for you!

Thanks Verteiron! People really get some creative ideas! Looks like I can use some ideas from his LOS function to help with placement.
User avatar
Justin
 
Posts: 3409
Joined: Sun Sep 23, 2007 12:32 am


Return to V - Skyrim