[v1.0] Fully 3D moving platform

Post your example zscripts/ACS scripts/etc here.

[v1.0] Fully 3D moving platform

Postby Apeirogon » Sun May 31, 2020 1:02 pm

Well, as title say. One of the realization of fully 3D platform, which uses specific actor as platform.
A little video demonstration

Github
https://github.com/MekBoss/fully_3d_platform
How to download it from Github
viewtopic.php?f=39&t=70332

It have some "advanced" features, for now only one. If you jump down from the platform you save you momentum from movement on the platform. Speed of the platform have influence on your speed when you jump down from it, in other words. Turn on in example for testing purpose.

If someone have some tips for improvement, feel free to say it here or on Github.
Last edited by Apeirogon on Wed Oct 21, 2020 1:01 pm, edited 2 times in total.
User avatar
Apeirogon
I have a strange sense of humour
 
Joined: 12 Jun 2017

Re: [Proof of concept] Fully 3D moving platform

Postby AFADoomer » Sun May 31, 2020 3:49 pm

Nice!

Not sure if this will help at all, but here's a stripped down version of my generic moving platforms that I put together a while back:
Code: Select allExpand view
// Moving Platforms
class Platform : Actor
{
   Array<Actor> touchers;
   Vector3[64] offsets;

   double moveangle, moved, user_movedist;

   Default
   {
      Radius 46;
      Height 12;
      MaxStepHeight 0;
      Speed 4;
      +CANPASS
      +DONTTHRUST
      +NOGRAVITY
      +SOLID
   }

   States
   {
      Spawn:
         MDLA A -1;
         Stop;
      Active:
         MDLA A -1;
         Stop;
      Inactive:
         MDLA A -1;
         Stop;
   }

   override void Touch(Actor toucher)
   {
      if (toucher == self || toucher.bNoGravity || toucher is "Platform" || toucher.pos.z == toucher.floorz) { return; }
      if (toucher.pos.z > pos.z + 32.0 || toucher.pos.z < pos.z - 16) { return; }
      if (touchers.Find(toucher) == touchers.Size()) { touchers.Push(toucher); }
   }

   override void PostBeginPlay()
   {
      moveangle = angle;

      bDormant = SpawnFlags & MTF_DORMANT;

      if (bDormant) { Deactivate(self); }
      else { Activate(self); }

      Super.PostBeginPlay();
   }

   override void Tick()
   {
      if (IsFrozen() || bDormant)
      {
         Actor.Tick();

         return;
      }

      CheckTouchers();

      Vector2 newpos = pos.xy + RotateVector((Speed, 0), moveangle);
      moved += Speed;

      if (CheckMove(newpos, 0) && (user_movedist <= 0 || moved <= user_movedist))
      {
         SetOrigin((newpos, pos.z), true);

         MatchMovement();
         Actor.Tick();
      }
      else
      {
         moveangle = (moveangle + 180) % 360;
         moved = 0;
         Actor.Tick();
      }
   }

   override bool CanCollideWith(Actor other, bool passive)
   {
      if (other.player || other.bIsMonster)
      {
         Touch(other);
         return true;
      }

      return true;
   }

   void CheckTouchers()
   {
      for (int i = 0; i < min(touchers.Size(), 64); i++)
      {
         if (touchers[i])
         {
            if (
               Distance3D(touchers[i]) > (Radius + touchers[i].radius) * 1.4 ||
               touchers[i].pos.z < pos.z + height ||
               !touchers[i].bOnMobj
            )
            {
               touchers.Delete(i);
               offsets[i] = (0, 0, 0);
            }
            else { offsets[i] = touchers[i].pos - pos; }
         }
         else { touchers.Delete(i); touchers.ShrinkToFit(); }
      }
   }

   void MatchMovement()
   {
      for (int i = 0; i < min(touchers.Size(), 64); i++)
      {
         if (
            touchers[i] &&
            (
               (Distance2D(touchers[i]) < (Radius + touchers[i].radius) * 1.4 && touchers[i].pos.z == pos.z + height) ||
               absangle(angle, AngleTo(touchers[i])) < 45 ||
               ((touchers[i].bOnMobj || (touchers[i].player && touchers[i].player.jumptics == 0)) && Distance3D(touchers[i]) < radius * 2)
            ) &&
            offsets[i] != (0, 0, 0)
         )
         {
            if (touchers[i].TryMove(pos.xy + offsets[i].xy, true))
            {
               touchers[i].SetOrigin(pos + offsets[i], true);
            }
         }
      }
   }

   override void Activate(Actor activator)
   {
      bDormant = false;
      Super.Activate(activator);
   }

   override void Deactivate(Actor activator)
   {
      bDormant = true;
      Super.Deactivate(activator);
   }
}
These handle 'bouncing' back and forth between endpoints (or a user-defined max move distance), and take their movement angle and speed from the actor. The effect works best with a 3D model for the platform. This particular one only moves on the x/y axis, but I have another variant that follow the path of a tracer, so can move on any axis.

You could also make the platform able to carry other actors by using a BlockThingsIterator to find touching objects, instead of just CanCollideWith.
User avatar
AFADoomer
 
Joined: 15 Jul 2003

Re: [Proof of concept] Fully 3D moving platform

Postby Enjay » Sun May 31, 2020 4:55 pm

Very nice, very smooth. I can see that it has some issues (for example, I rode the platform right to the end and got stuck in the wall) but the travelling part of the ride seemed very solid.
User avatar
Enjay
Everyone is a moon, and has a dark side which he never shows to anybody. Twain
 
 
 
Joined: 15 Jul 2003
Location: Scotland

Re: [v1.0] Fully 3D moving platform

Postby Apeirogon » Mon Jun 01, 2020 1:22 pm

Now platform should not push player through walls into the void, I added the necessary restrictions.
Also was added basic physics. Now you store you momentum from moving on platform when you jump down. But it easily can be turned off, since its only a function flag.
User avatar
Apeirogon
I have a strange sense of humour
 
Joined: 12 Jun 2017


Return to Script Library

Who is online

Users browsing this forum: No registered users and 0 guests