UE1 - UT Who wants to help debug some accessed nones?

  • Two Factor Authentication is now available on BeyondUnreal Forums. To configure it, visit your Profile and look for the "Two Step Verification" option on the left side. We can send codes via email (may be slower) or you can set up any TOTP Authenticator app on your phone (Authy, Google Authenticator, etc) to deliver codes. It is highly recommended that you configure this to keep your account safe.

Rajada

Member
Jan 21, 2008
213
0
16
rajada.tumblr.com
I'll start with this one:

ScriptWarning: ClusterMineRing PM-Tenant.ClusterMineRing8 (Function RajMutators2.MineRing.Touch:001F) Accessed None

Here is what I would call the "relevant" code

Code:
simulated function Touch( actor Other )
{

	if ( Other.IsA('Pawn'))
	{	
	RM2ProximityMine(OwnerMine).SetTimer(0.1,True);	
	PlaySound(DetSound);
	}	
}
simulated function CheckTouchList()
{
	local int i;

	for (i=0;i<4;i++)
		if ( Touching[i] != None )
			Touch(Touching[i]);
}

So why would THIS cause an accessed none?
 
Nov 4, 2001
2,196
0
0
36
The Kitchen
The Accessed None only appears in Touch, so focus on that function. CheckTouchList looks fine.

Here's what you need to insert:

Code:
simulated function Touch( actor Other )
{
	// check to ensure Other!=none
	if ( Other!=none && Other.IsA('Pawn'))
	{
		// you may not need this, but I've done similar things and set it up like so
		if (OwnerMine!=none && OwnerMine.IsA('RM2ProximityMine'))
			RM2ProximityMine(OwnerMine).SetTimer(0.1,True);	
		PlaySound(DetSound);
	}	
}

Try this out. You want to check to be sure that Other!=none in the main if statement, then probably ensure that the proximity mine is not none.

Here's some functional code (works online too last I checked) I've made recently that does sorta the same thing. This is a proxy class spawned by a Sh!tCanister when it enters a waterzone. Soon as the canister goes into the waterzone, this projectile is spawned and remains attached. Once something comes in contact with it, it detonates the canister. It has a much wider collision radius than the original canister, of course, and the original canister can still be shot and detonated manually.

Also, what class is this in? You can make something like this expand Projectile without any trouble. I would recommend using Projectile over Effects for something that isn't expendable online. It also checks to be sure that the colliding actor isn't on the same team as the instigator, which you may find useful for a proximity mine.

I had a lot of Accessed Nones with this code until UArchitect helped me crush them all. Now it behaves quite well!

Code:
class CanisterCollisionProxy expands EXUGenericProjectiles;	// this arms a Sh!t Canister when it enters a waterzone

function ProcessTouch (Actor Other, vector HitLocation) 
{
	// ensure Other!=none, Instigator!=none, and, optionally, that Other!=Instigator (so it won't blow up the player who launched it)
	if ( (Other!=none) && (Instigator!=none) && (Other!=Instigator) )
	{
		// check that the Instigator's team is not the same as Other's team if it's a team game
		if ( (!level.game.bteamgame) || (Other.IsA('Pawn')) && (Pawn(other).playerreplicationinfo!=none) && (Instigator.PlayerReplicationInfo!=none) && (Pawn(other).playerreplicationinfo.team!=instigator.playerreplicationinfo.team) )
		{
			//log("Touched actor is: "$Other);
			if ( (owner!=none) && owner.IsA('Sh!tCanister') )
			{
				// you can use SetTimer instead of calling Timer() if you don't want it to detonate immediately
				Sh!tCanister(Owner).Timer();
				Destroy();
			}
		}
	}
}

defaultproperties
{
	CollisionHeight=64.000000
	CollisionRadius=128.000000
	bCollideWorld=False
	bHidden=True
	RemoteRole=ROLE_SimulatedProxy
	Physics=PHYS_Trailer
	LifeSpan=0.0
}

Haha, I forgot this board censors stuff :I
 
Last edited:

Wormbo

Administrator
Staff member
Jun 4, 2001
5,913
36
48
Germany
www.koehler-homepage.de
Code questions should really go into the Unreal Development >> Coding area.

About the Accessed None problem: Touch is never called with None parameter in that constellation, so the "Other" variable can't be the reason. Checking for None there would be wasted time as that can never happen anyway.
Note that you call "RM2ProximityMine(OwnerMine).SetTimer()" there without any further checks. That's probably the reason fro your Accessd None, either because OwnerMine is None or because it's not a RM2ProximityMine. You made Touch simulated, so if it is really supposed to be called clientsidely, make sure OwnerMine is properly replicated. Also, replication isn't necessarily instant, so add a corresponding check. Since you need to check for None and proper type, you can (and should!) combine those two checks as follows:
Code:
if (RM2ProximityMine(OwnerMine) != None)
  OwnerMine.SetTimer(0.1, True);
Note that there's absolutely no need to typecast OwnerMine just to call SetTimer on it, unless it's a variable declared as type Object. (SetTimer() is declared in class Actor already.)

FYI:
The term "X != None && X.IsA('Y')" consists of four operations: "&&", "!=", access "X" (this may cause an Accessed None, which is why you need the != check in the first place) and "call IsA on X".
"Y(X) != None" on the other hand are only two operations: "typecast X to Y" and "!=".
 
Nov 4, 2001
2,196
0
0
36
The Kitchen
FYI:
The term "X != None && X.IsA('Y')" consists of four operations: "&&", "!=", access "X" (this may cause an Accessed None, which is why you need the != check in the first place) and "call IsA on X".
"Y(X) != None" on the other hand are only two operations: "typecast X to Y" and "!=".
Hey, that's cool; I never knew you could do that.

I shoulda noted that I'm not super great at coding either, but my code does at least work :p
 

Rajada

Member
Jan 21, 2008
213
0
16
rajada.tumblr.com
Okay wow, that really helped, I squished like 4 other Accessed Nones with that help. Now, this is a projectile:

Code:
simulated function ProcessTouch (Actor Other, Vector HitLocation)
	{
	local RM2MelonRind W;
	local PowerBlast h;
	
	headspot.z = pawn(Other).BaseEyeHeight-35;
	headspot.x = 0;
	headspot.y = -4;


	
	if ( Other.IsA('Pawn') &&(Other != None) && (HitLocation.Z - Other.Location.Z > 0.62 * Other.CollisionHeight))
				{
				W = spawn(class'RajMutators2.RM2MelonRind',,,HitLocation);	//+ HitNormal*16
		W.Stick(pawn(other), headspot);
				    		w.bCanHitOwner = False;
    		h = spawn(class'PowerBlast',,,Hitlocation);
						h.drawscale *=3.0;
						h.lifespan =1.0;

    		
    	
    		w.settimer(0.5, true);
				}

		else if ((Other != instigator) &&(Other != None) && (Rocket(Other) == none)) 
			Explode(HitLocation,Normal(HitLocation-Other.Location));
	}

That gives me:

ScriptWarning: RM2Watermelon CTF-Egocentric.RM2Watermelon0 (Function RajMutators2.RM2Watermelon.Flying.ProcessTouch:0017) Accessed None
 

Wormbo

Administrator
Staff member
Jun 4, 2001
5,913
36
48
Germany
www.koehler-homepage.de
Remember, code is executed as you read English text: From top to bottom and from left to right. If other words, if a statement is on a line above or one the same line to the left, it is executed earlier. Stuff to the right on the same line or on a line below is executed later.
So, if you access Other to call IsA() already, the None check afterwards won't be able to prevent the Accessd None.


And like I said: Combine the None and type checks. Unlike IsA(), that combined typecast None check is safe.
 
Last edited:

Rajada

Member
Jan 21, 2008
213
0
16
rajada.tumblr.com
So i've got this weapon that works totally fine in single player. In a game playing on the same PC as the server I get an accessed none in the projectile's PostBeginPlay but the weapon still works. However If I play on a server with it and try to fire or alt fire I crash after about 1 second. Also, you can see it fires off to the side in one direction only rather than from the gun. I have also had others on my server tell me that they do not crash when firing, only get the 'firing to the side' thing, but we all have the same files and I doubt I am missing anything. The log indicates:

Critical: appError called:
Critical: Assertion failed: ActorClass [File:C:\Nerf\Engine\Src\UnChan.cpp] [Line: 714]
Critical: Windows GetLastError: The system cannot find the file specified. (2)

However I am not missing any files needed to play with it since it works fine in singleplayer.

relevant weapon code:

Code:
simulated state AltFiring
{

function Projectile ProjectileFire(class<projectile> ProjClass, float ProjSpeed, bool bWarn)
	{
local Projectile S;
		local int i;
		local vector Start,X,Y,Z;
		local Rotator StartRot, AltRotation;
		local float decision;
		local Pawn PawnOwner;


	PawnOwner = Pawn(Owner);
	StartRot = Owner.Rotation;
						GetAxes(PawnOwner.ViewRotation,X,Y,Z);
Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z; 
AdjustedAim = PawnOwner.AdjustToss(ProjSpeed, Start, AimError, True, bWarn);	
			if (AmmoType.UseAmmo(1)) 
			{
				 AltRotation = Rotation;
				AltRotation.Yaw += FRand()*300-100;
				AltRotation.Roll += FRand()*9000-4500;
		
		
							
				S = Spawn(Class'RM2SteelBall',,, Start, AltRotation);
				
        		}						


	
}
Begin:
	FinishAnim();	
	Finish();			
}

I think the problem lies in this part of the code somewhere, and I'm not certain whether the Accessed None in the projectile still exists, but I'm doubtful it would cause either of the errors I'm experiencing. Any ideas/suggestions/wild guesses?
 

Rajada

Member
Jan 21, 2008
213
0
16
rajada.tumblr.com
Nope, you guys helped me squish em all. Thanks again! It was especially helpful to know what an accessed none is. I've almost eliminated all the bugs from this mutator, but I might throw another thread up later depending on the amount of 'other bugs' I can't solve.
 

Wormbo

Administrator
Staff member
Jun 4, 2001
5,913
36
48
Germany
www.koehler-homepage.de
For completeness' sake: If you happen to experience "Accessed Null class context", that's the same as an Accessed None, but on variables declared as class<X> and in combination with default value access or static function calls. Same rules for fixing apply.

Since you already fixed the Accessed Nones, you won't see "Attempted to assign variable through None", which is always preceeded by an Accessed None and is caused by a None variable on the left side of a variable assignments through the = operator.