2013-03-26 9 views
5

मैं एकता में 2 डी प्लेटफार्म लिख रहा हूं और मैं खिलाड़ी को एक चलती प्लेटफॉर्म पर रहने की कोशिश कर रहा हूं। मैंने एक या दो दिन के लिए खोज और टिंकरिंग की है, और मुझे कोई भाग्य नहीं है।मूविंग प्लेटफॉर्म पर बने रहें

असल में, मुझे चरित्र को छूने पर मंच के साथ आगे बढ़ने की कोशिश करने के लिए कहा गया है। सबसे पहले, अगर मैं OnTriggerEnter() से संबंधित कुछ भी उपयोग करता हूं, तो खिलाड़ी मंच के माध्यम से सही हो जाता है। अगर मैं ऑनकॉलिजनइंटर() (प्लेयर पर एक कैरेक्टर कंट्रोलर और प्लेटफॉर्म पर बॉक्सकॉलिडर के साथ) करता हूं, तो कुछ भी नहीं होता है। ये दो चीजें हैं जिन्हें मैंने सबसे अधिक सुझाव दिया है। दूसरा मंच के साथ खिलाड़ी को parenting है, लेकिन यह स्पष्ट रूप से "समस्याओं" का कारण बनता है (अक्सर कहा, कभी समझाया नहीं)।

तो, मैं चलने वाले प्लेटफ़ॉर्म पर रहने के लिए खिलाड़ी को कैसे प्राप्त कर सकता हूं?

public class MovingPlatform : MonoBehaviour 
{ 
private float useSpeed; 
public float directionSpeed = 9.0f; 
float origY; 
public float distance = 10.0f; 

// Use this for initialization 
void Start() 
{ 
    origY = transform.position.y; 
    useSpeed = -directionSpeed; 
} 

// Update is called once per frame 
void Update() 
{ 
    if(origY - transform.position.y > distance) 
    { 
     useSpeed = directionSpeed; //flip direction 
    } 
    else if(origY - transform.position.y < -distance) 
    { 
     useSpeed = -directionSpeed; //flip direction 
    } 
    transform.Translate(0,useSpeed*Time.deltaTime,0); 
} 

यहाँ और (अद्यतन में) प्लेयर के आंदोलन के लिए कोड है:: यहाँ चलती मंच के लिए कोड है

CharacterController controller = GetComponent<CharacterController>(); 
    float rotation = Input.GetAxis("Horizontal"); 
    if(controller.isGrounded) 
    { 
     moveDirection.Set(rotation, 0, 0); //moveDirection = new Vector3(rotation, 0, 0); 
     moveDirection = transform.TransformDirection(moveDirection); 

     //running code 
     if(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) //check if shift is held 
     { running = true; } 
     else 
     { running = false; } 

     moveDirection *= running ? runningSpeed : walkingSpeed; //set speed 

     //jump code 
     if(Input.GetButtonDown("Jump")) 
     { 
      //moveDirection.y = jumpHeight; 
      jump(); 
     } 
    } 
    moveDirection.y -= gravity * Time.deltaTime; 
    controller.Move(moveDirection * Time.deltaTime); 

संपादित करें: मुझे लगता है यह करने के लिए हो सकता है मैं कैसे 'के साथ मैं खिलाड़ी और मंच को परिभाषित करता हूं, लेकिन मैंने विभिन्न संयोजनों की कोशिश की है। यदि मंच एक ट्रिगर (इसके कोलाइडर पर) है, तो खिलाड़ी लगातार इसके माध्यम से चला जाता है। यदि नहीं, तो मैं ऑनट्रिगर कार्यों का उपयोग नहीं कर सकता। मेरे पास खिलाड़ी और मंच दोनों से जुड़ा एक कठोर है, लेकिन ऐसा कुछ भी प्रभावित नहीं होता है। जब खिलाड़ी कुछ सेटअप में मंच पर जाता है, तो वह झटके और अक्सर गिरने से समाप्त होता है।

+0

मैं Unity3D उपयोग नहीं किया है, लेकिन ऐसा लगता है 'moveDirection + = theplatform कुछ करने के लिए संभव है।जब प्लेटफॉर्म पर चरित्र होता है तो moveDirection'? – mbeckish

+0

मैंने कोशिश की है, लेकिन मुझे ऑनट्रिगर और ऑनकॉलिजन फ़ंक्शंस के साथ समस्याओं में भागना प्रतीत होता है, जो उस समय "जब खिलाड़ी मंच पर है" के लिए ज़िम्मेदार होगा। मुझे लगता है कि मुझे अपनी वस्तुओं को परिभाषित करने के तरीके के साथ क्या करना है, लेकिन मुझे यकीन नहीं है कि उन्हें परिभाषित करने का उचित तरीका यह है कि यह काम कर सकता है। – muttley91

+0

इसके अलावा, आपको यह सुनिश्चित करने की आवश्यकता होगी कि चरित्र की चाल Direction.y आपके प्लेटफ़ॉर्म की चाल से कम कभी नहीं है। या, अन्यथा आप तब तक गिरेंगे (जब तक यूनिटी 3 डी फ्रेमवर्क आपके लिए स्वचालित रूप से संभालता है?) – mbeckish

उत्तर

1

क्या आप की जरूरत मंच पर एक दूसरे कोलाइडर हो रहा है। यह सुनिश्चित करने के लिए कि आपका चरित्र नियंत्रक काम कर रहा है, मुख्य कोलाइडर में isTrigger = false है। दूसरा वाला isTrigger = true के साथ चलता है और इसका एकमात्र फ़ंक्शन यह पता लगाने के लिए है कि प्लेयर प्लेटफ़ॉर्म से जुड़ा हुआ है जब OnTriggerEnter को OnTriggerExit पर प्लेटफ़ॉर्म कहा जाता है और छोड़ देता है।

जैसा कि आपके पास एक ही प्रकार के 2 कोलाइडर नहीं हो सकते हैं (मुझे लगता है कि आपको बॉक्स कोलाइडर की आवश्यकता है), अपने प्लेटफ़ॉर्म गेम ऑब्जेक्ट के नीचे एक खाली बच्चा बनाएं और बॉक्स कोलाइडर को असाइन करें। मैं आमतौर पर अपनी सामग्री को साफ करने के लिए एक्शनमटेरियल नामक एक विशेष भौतिकी सामग्री लेता हूं। यदि आप परतों का उपयोग कर रहे हैं और tweaked टकराव मैट्रिक्स सुनिश्चित है कि आपकी टक्कर physX द्वारा संभाला जाता है।

+0

क्या मैं दो ऑब्जेक्ट्स के बजाय एक ही ऑब्जेक्ट पर दो अलग-अलग कॉलर (एक बॉक्स, एक कैप्सूल) का उपयोग कर सकता हूं, और उन्हें दोनों को स्क्रिप्ट स्क्रिप्ट चाहिए? इसके अलावा, मैं परतों का उपयोग नहीं कर रहा हूं और कोई tweaked टकराव मैट्रिक्स नहीं है। – muttley91

+0

विभिन्न कोलाइडर की अनुमति है। लेकिन ध्यान रखें कि एक कैप्सूल कोलाइडर कहीं अधिक महंगा है। तो यदि घन आकार है, तो आप बच्चे ऑब्जेक्ट समाधान का उपयोग कर बेहतर हैं। कोई परत नहीं, कोई टकराव मैट्रिक्स मैनिपुलेशन => कोई जटिलता नहीं बढ़ी है;) जब आप प्रदर्शन समस्याओं में भाग ले रहे हों तो आपको केवल उस सामान की आवश्यकता होगी। मैं आईओएस के लिए विकास कर रहा हूं इसलिए प्रदर्शन हमेशा मेरे लिए एक मुद्दा है – Kay

+0

आह मेला पर्याप्त है! तो स्पष्ट होना, आपका मतलब है कि दृश्य में दो गेम ऑब्जेक्ट्स हैं? आप विशेष रूप से एक वस्तु को दूसरे बच्चे के बच्चे कैसे बनाते हैं? – muttley91

1

यह करने का यह सबसे अच्छा तरीका नहीं है, लेकिन आप खिलाड़ी से चलने वाले प्लेटफ़ॉर्म पर रेकास्ट कर सकते हैं। यदि रेकास्ट "मूविंगप्लाफ्फ़्ट" हिट करता है तो आप यह निर्धारित करने के लिए वाई अक्ष पर अंतर की जांच कर सकते हैं कि खिलाड़ी "ऑनप्लाफ़्ट" पर विचार करने के लिए पर्याप्त है या नहीं। फिर आप सामान्य रूप से खिलाड़ियों की स्थिति को समायोजित कर सकते हैं।

एक उदाहरण होगा:

private bool isOnMovingPlatform; 
private float offsetToKeepPlayerAbovePlatform = 2.2f; 
private float min = 0.2f; 
private float max = 1.2f; 

private void Update() 
{ 
RaycastHit hit; 
if(Physics.Raycast (player.position, player.TransformDirection(Vector3.down), out hit)) 
{ 
    if(hit.transform.name.Contains("MovingPlatform")) 
    { 
     Transform movingPlatform = hit.collider.transform; 

     if(movingPlatform.position.y - player.position.y <= min && movingPlatform.position.y - player.position.y >= max) 
     { 
      isOnMovingPlatform = true; 
     } 
     else 
     { 
      isOnMovingPlatform = false; 
     } 
    } 

    if(isOnMovingPlatform) 
    { 
     player.position = new Vector3(hit.transform.x, hit.transform.y + offsetToKeepPlayerAbovePlatform, 0); 
    } 
} 
} 
+0

बस उत्सुक है क्योंकि मैं इसे करने की कोशिश कर रहा हूं, न्यूनतम, अधिकतम और ऑफ़सेट, क्या वे प्लेटफॉर्म के आकार से संबंधित हैं? – muttley91

+0

जरूरी नहीं है। न्यूनतम और अधिकतम केवल श्रेणियां हैं ताकि आप जान सकें कि खिलाड़ी मंच के लिए प्रासंगिक कहां है। यदि खिलाड़ी वाई मान उदाहरण के लिए अधिकतम 5 से ऊपर है, तो यह स्पष्ट है कि वह मंच पर नहीं है और इसके विपरीत है। श्रेणियों को तब तक बदलें जब तक आप फ्लोट की अच्छी जोड़ी न लें। सिद्धांत रूप में वे मंच की ऊंचाई से प्राप्त कर सकते हैं लेकिन उन्हें नहीं करना है। –

0

This Unity Answers page मदद कर सकता है।

+0

यह वास्तव में बहुत अच्छा है। लेकिन आपको इसे टिप्पणी के रूप में पोस्ट करना चाहिए या अधिक जानकारी प्रदान करना चाहिए। उत्तर में केवल एक लिंक वाला जवाब होगा (मैंने अभी कुछ खो दिया है) – Kay

0

आप खिलाड़ी को गेमोबजेक्ट्स को मंच के रूप में परिवर्तित करने के बराबर माता-पिता को बदल सकते हैं। यह खिलाड़ी को तब भी चलने की अनुमति देता है जब वे उस पर हों। पहचान के लिए एक Raycast थोड़ा धीमा है लेकिन काम पूरा हो जाता है।

0

हमने स्लाइडरजॉइंट 2 डी का उपयोग करके समस्या को हल किया और चलती प्लेटफॉर्म पर चरित्र के गुरुत्वाकर्षण पैमाने को शून्य पर सेट किया। यहाँ पूरे स्पष्टीकरण के साथ लिंक है:

http://spacelizardstudio.com/devblog/index.php/2016/03/02/unity-a-guide-to-moving-platforms/

+0

आपको लिंक से प्रासंगिक जानकारी जोड़नी चाहिए ताकि लिंक अभी भी उपयोगी और प्रासंगिक हो, भले ही लिंक मर जाए। – drneel

संबंधित मुद्दे