Jump to content

danidomen

Members
  • Posts

    4
  • Joined

  • Last visited

Posts posted by danidomen

  1. Hi all!

    Well! I think that is the best "approach" I can do, and is near the perfect expected result, so I share with all the community how I made it (really is possible to write better code, but is my first try with Lua and with Leadwerks haha)

    On VRPlayer I made the following modifications:

    On the script variables declaration at the top:

    Script.pickradius=0.05
    Script.hitBallTime=0
    Script.hitBallDelay=50
    Script.clickUsed=false
    Script.clickUseTime=0
    Script.clickUseDelay=500

    On the "Script:Start()" function, before the "--Create teleporter beam" comment add this

    function Script:Start()
      blablabla
      
      self.picksphere=Model:Sphere()
      self.picksphere:SetColor(1.0,0.0,0.0) 
      self.picksphere:SetPickMode(0) 
      self.picksphere:SetScale(self.pickradius*2.0)
      
      --Create teleporter beam
      blablabla

    Add this new function VRPlayer_TouchingItems

    function VRPlayer_TouchingItems(entity,extra)
    	if entity==extra then return end
    	local self = tolua.cast(extra,"Entity").script
    	local mass = entity:GetMass()
    	local time = Time:GetCurrent()
    	if self.clickUsed == true and time-self.clickUseTime>self.clickUseDelay then
    		self.clickUseTime = 0
    		self.clickUsed = false
    		--This is needed to have control on not to make click so quickly (open/close/open/close the door because ButtonDown). Reason explained below
    	end
    		local pos = self.currentcontroller:GetPosition(true)
    		local d = entity:GetDistance(pos,true)
    		local usableentity = self:FindUsableEntity(entity)
    		if d <= self.grippadding and usableentity~=nil then
    			if VR:GetControllerButtonDown(VR.Right,VR.TriggerButton)==true then
          			--Why use ButtonDown and not hit, is because a lot of times Hit is not reachable, so to "stop" on continuos clicking, i make this control
    				if self.clickUsed == false then
    					self.clickUsed = true
    					self.clickUseTime = time
    					usableentity.script:Use(self)
    				end
    			else
    				self.hitBallTime = time
    				self.picksphere:SetPosition(pos);
    			end
    		else
    			if time-self.hitBallTime>self.hitBallDelay then
    				self.picksphere:SetPosition(0,0,0);
    			end
    		end
    end

    Add this new function VRPlayer_IntersectingController

    function VRPlayer_IntersectingController(controller,extra)
    	if controller~=nil then
    		local aabb = AABB()	
    		aabb.min = controller:GetPosition(true)
    		aabb.max = aabb.min
    		aabb.min = aabb.min - Vec3(extra.grippadding)
    		aabb.max = aabb.max + Vec3(extra.grippadding)
    		aabb:Update()
    		extra.currentcontroller = controller
    		extra.currentcontrollerindex = n
    		world:ForEachEntityInAABBDo(aabb,"VRPlayer_TouchingItems",extra.entity)
    	end
    end

    On the "Script:UpdateWorld()" function, before the "----Check if teleporter is active and the button was released" comment add this

    function Script:UpdateWorld()
    	local n
    	for n=0,1 do
    		local controller = VR:GetControllerModel(VR.Left+n)
    		VRPlayer_IntersectingController(controller,self)
    	end

    And last, taked from FPSPlayer, add this new function to VRPlayer script

    function Script:FindUsableEntity(entity)
    	while entity~=nil do
    		if entity.script then
    			if type(entity.script.Use)=="function" then
    				--If "enable" has not been set, it still won't be "false" so this will pass:
    				if entity.script.enabled~=false then
    					return entity
    				else
    					return nil
    				end
    			end
    		end
    		entity = entity:GetParent()
    	end
    	return nil
    end
    • Upvote 1
  2. Hi @Josh

    Fine, I created the functions understanding a bit more how you used to "grab" the objects. So I have writed this, and is a bit better, but the ball is stuck on the air on front of the "Use" entity, although the controller not touched when I move away the controller from the "Use" entity. I tried with a two "else" clausules but with not sucess because then the ball is never "positioned" (I supposed that is positioned but as fast that they never appear on screen because of the "else")

    function VRPlayer_TouchingItems(entity,extra)
    	if entity==extra then return end
    	local self = tolua.cast(extra,"Entity").script
    	local mass = entity:GetMass()
        local pos = self.currentcontroller:GetPosition(true)
        local d = entity:GetDistance(pos,true)
        if d <= self.grippadding then
          local usableentity = self:FindUsableEntity(entity)
          if usableentity~=nil then
            if VR:GetControllerButtonHit(VR.Right,VR.TriggerButton)==true then
              usableentity.script:Use(self)
            else
              self.picksphere:SetPosition(pos);
            end
          else
          	--With this next line, the ball never is "positioned" because this seems to be continuosly updated at ms frequency, so the above SetPosition is like nothing
          	--self.picksphere:SetPosition(0,0,0);
          end
        else
        	--Same with this next line, the ball never is "positioned" because this seems to be continuosly updated at ms frequency, so the above SetPosition is like nothing
          	--self.picksphere:SetPosition(0,0,0);
        end
    
    	if entity:CountVisibleChildren()>0 then
    		local n
    		for n=0,entity:CountChildren()-1 do
    			VRPlayer_TouchingItems(entity:GetChild(n),extra)
    		end
    	end
    end
    
    function VRPlayer_IntersectingController(controller,extra)
    	if controller~=nil then
    		local aabb = AABB()	
    		aabb.min = controller:GetPosition(true)
    		aabb.max = aabb.min
    		aabb.min = aabb.min - Vec3(extra.grippadding)
    		aabb.max = aabb.max + Vec3(extra.grippadding)
    		aabb:Update()
    		extra.currentcontroller = controller
    		extra.currentcontrollerindex = n
    		world:ForEachEntityInAABBDo(aabb,"VRPlayer_TouchingItems",extra.entity)
    	end
    end
    
    function Script:UpdateWorld()
    	local n
    	for n=0,1 do
    		local controller = VR:GetControllerModel(VR.Left+n)
    		VRPlayer_IntersectingController(controller,self)
    	end
       A LOT OF OTHER STUFF

     

  3. Hi @AggrorJorn,

    Sure, here is the video. One half is with VR with the strange "pick" function to "use" the objects, and the other half of the video is with FPSPlayer and nice pick/use of switches and doors.

    Yes, I know that "pick" is not the way to do this on VR (the switch directly not detect nothing, also the ball is "printed" always on what is like the mass center of the controller and not when "collision" happens), but I don't find info explaining how the collision system works, :( or how detect collision at the controller with another object and "callback" to the Use function of the object.

     

     

    • Like 1
  4. Hi,

    I have some switches and doors (SwingingDoors) that have Use function and calls to open or light up the rooms. But now I want that when my VR controller collide with the door or the light, first detect that I can "interact" with it (atm painting a Sphere...) and when I click on controller trigger, call to "Use" function of the collided entity (door or switch). Now, I replicated the code from FPSPlayer to interact with the E Key, and is "working" but is very awful :(

    I'm trying to write what I'm doing (very very very bad) on VRPlayer

    function Script:UpdateWorld()
    
    		local pickInfo = PickInfo()
    		--Usable object with Trigger Button: DANI
    		if VR:GetControllerButtonDown(VR.Right,VR.TriggerButton)==true then
    			
    			
    			local p0 = controller:GetPosition(true)
    			local p1 = Transform:Point(0,0,self.useDistance,controller,nil)
    			if self.entity.world:Pick(p0,p1, pickInfo, self.pickradius, true) then 
    				
    				--Looks for any entity in the hierarchy that has a "Use" function
    				local usableentity = self:FindUsableEntity(pickInfo.entity)
    				
    				if usableentity~=nil then
    					
    					--Use the object, whatever it may be
    					usableentity.script:Use(self)
    				end
    			end
    		end
    		self.canUse = false
    		pickInfo = PickInfo()
    
    		local p0 = controller:GetPosition()
    		local p1 = Transform:Point(self.useDistance,self.useDistance,self.useDistance,controller,nil)
    		if self.entity.world:Pick(p0,p1, pickInfo, self.pickradius, true) then 
    			if self:FindUsableEntity(pickInfo.entity)~=nil then
    				self.picksphere:SetPosition(pickInfo.position);
    				self.canUse=true
    			else
    				local mass = pickInfo.entity:GetMass()
    				if mass>0 and mass<=self.maxcarryweight then
    					self.canUse = true
    				end
    			end
    		else
    			self.picksphere:SetPosition(0,0,0)
    		end

     

×
×
  • Create New...